Friday, January 26, 2007

Java puzzler: field hide-and-seek

Someone recently asked me to explain the rules for field access in Java, and it sparked the little test program you see below. Can you guess the number sequence it prints?

class Class1 {
String data;

Class1(String data) {
this.data = data;
}

String getData() {
return this.data;
}
}

class Class2 extends Class1 {
String data;

Class2(String data, String superData) {
super(superData);
this.data = data;
}
}

public class Test {
public static void main(String[] args) {
Class1 obj1 = new Class1("1");
Class2 obj2 = new Class2("2", "3");

System.out.println(obj1.data);
System.out.println(obj2.data);
System.out.println((false ? obj1 : obj2).data);

System.out.println(obj1.getData());
System.out.println(obj2.getData());
System.out.println((false ? obj1 : obj2).getData());
}
}

It goes to show three interesting things (which are perfectly logical, we just don't think about them often):
  • compile-time type of the ?: expression is the most specific common supertype of the compile-time types of its two target subexpressions,
  • selection of target type for field access happens at compile time (no "virtual fields" in Java),
  • compile-time type of "this" expression is the class that declares the method,


Remember folks, avoid both field hiding and direct access to fields in the first place, so your code doesn't become a puzzler :-)

1 comment:

Arpan said...

What a question man!!
I loved it very much. Superb question full marks.