Monday, May 4, 2009

Java assignment expression

Java has an assignment expression, not just an assignment statement. This is one of the things it inherited from C. Java's assignment expression is more restricted than C's, but it still can be a bit scary. Consider the following:


boolean b = false;
if (b = true)
System.out.println("B is true.");


This code will print


B is true.


which may surprise you, if you didn't look closely, because you probably understood that the almost identical bit of code:


boolean b = false;
if (b == true)
System.out.println("B is true.");


will print nothing.

Java's "if" statement only accepts boolean-valued expressions in its test, which means that some of the worst types of accidental mistakes from C will not occur in Java; the following code will not compile:


int i = 2;
if (i = 3)
System.out.println("I is 3.");


However, other rather frightening bits of Java code are legal, and do compile, and require a fair bit of thought to understand. Consider these snippets from the Java Language Specification itself:


int i = 2;
int j = (i=3) * i;
System.out.println(j);
int a = 9;
a += (a = 3);
System.out.println(a);
int b = 9;
b = b + (b = 3);
System.out.println(b);


This code prints 9, 12, and 12. But it takes a fair amount of thought to understand why, and therefore many people abhor the assignment expression, and wish that Java had only included an assignment statement. I'm generally sympathetic to this view; I certainly don't enjoy code like the above, and would never write such code myself (and would probably re-write such code if I came upon it while maintaining a system).

However, consider this example, from Derby's SQLInteger.java:


public SQLInteger(Integer obj) {
if (isnull = (obj == null))
;
else
value = obj.intValue();
}


I think this is actually quite clean, and appealing. Let's break it down:
  1. Check the passed-in argument, "obj", to see if it is null or not, and save the answer in the member field "isnull".
  2. If "obj" was in fact null, do nothing more.
  3. Otherwise, "obj" was not null, so call the intValue() method on it, and save the result in the member field "value".
The use of the assignment expression is clear, the code is simple and direct, and I approve of the style. I think this shows that there is room for good uses of the assignment expression after all.

No comments:

Post a Comment