Konstantin, On 4/6/21 06:41, Konstantin Kolinko wrote:
вс, 4 апр. 2021 г. в 13:24, André Warnier (tomcat/perl) <[email protected]>:Hi. I have a question which may be totally off-topic for this list, but this has been puzzling me for a while and I figure that someone here may be able to provide some clue as to the answer, or at least some interesting ponts of view. In various places (including on this list), I have seen multiple occurrences of a certain way to write a test, namely : if (null == request.getCharacterEncoding()) { as opposed to if (request.getCharacterEncoding() == null) { Granted, the two are equivalent in the end.Some programming languages have rules, in what order an expression is evaluated. E.g. the left side is evaluated first, the result is stored in a register (memory) of a CPU, then the right side is evaluated and the result is stored, then it is followed by a comparison and a conditional jump. Thus the two variants are not equivalent. (Well, as null is a zero and not really a specific value, maybe it does not need evaluation and a memory register to store it.)
JVM uses a stack and not registers, but of course many architectures (like most RISC) do use registers under the hood, so there is a bit of mapping here and there, at multiple levels. Then x86 is accumlator-based but also has a few registers, and that number grows with each processor revision.
Anyhow, Java bytecode has primitives for loading null values onto the stack, so it both has a definite value (probably 0, I've never bothered to dig into it too much) and it is definitely loaded into registers (well, onto the stack).
Further, JLS says that class members without explicit definitions get whatever the equivalent of "0" is in their data type. References are assigned "null", so null is probably == 0, though they could go old-school and use 0xdeadbeef like some C compilers back in the day.
In Java the Java Language Specification dictates the evaluation order, "15.7.1 Evaluate Left-Hand Operand First". I vaguely remember that in the C language the evaluation order in such expressions is unspecified. https://docs.oracle.com/javase/specs/ If one side of an expression can have unexpected side effects (like a function call or a null pointer dereference can have), I prefer them to be evaluated first. Thus my preference is for "(request.getCharacterEncoding() == null)". Otherwise, another point of view to consider is readability of the code. If the function call is some lengthy expression, " (null == request.getCharacterEncoding()) " may be more readable when formatting the code results in wrapping the lengthy expression, splitting it into several lines. I think that I should also mention the well-known construct when a comparison is done by calling the "equals()" method on some constant value: CONSTANT_VALUE.equals(someFunction()) In this case the "CONSTANT_VALUE" is known to be non-null, and thus calling its method cannot result in a NullPointerException. (In more complex cases the static method "Objects.equals()" helps to compare two values in a null-aware way).
In a way, this makes "null == thing" more consistent, because null is the constant in this case. You can't call null.equals(), of course, but it's the same idea... though for the opposite reason: in your case, you want to avoid both NPE and needless null-avoidance code.
-chris --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
