Wednesday, January 20, 2010

Puzzle 69: Fade to Black











 < Day Day Up > 







Puzzle 69: Fade to Black



Suppose that you can't modify classes X and C in the previous puzzle (Puzzle 68). Can you write a class whose main method reads the value of the field Z in class X.Y and prints it? Do not use reflection.













Solution 69: Fade to Black



At first, this puzzle may appear impossible. After all, the class X.Y is obscured by a field of the same name, so an attempt to name it will refer to the field instead.



In fact, it is possible to refer to an obscured type name. The trick is to use the name in a syntactic context where a type is allowed but a variable is not. One such context is the region between the parentheses in a cast expression. The following program solves the puzzle by using this technique and prints Black as expected:





public class FadeToBlack {

public static void main(String[] args){

System.out.println(((X.Y)null).Z);

}

}




Note that we are accessing the Z field of class X.Y by using an expression of type X.Y. As we saw in Puzzles 48 and 54, accessing a static member using an expression in place of a type name is a legal but questionable practice.



You can also solve this puzzle without resorting to questionable practices, by using the obscured class in the extends clause of a class declaration. Because a base class is always a type, names appearing in extends clauses are never resolved as variable names. The following program demonstrates this technique. It too prints Black:





public class FadeToBlack {

static class Xy extends X.Y { }



public static void main(String[] args){

System.out.println(Xy.Z);

}

}




If you are using release 5.0 or a later release you can also solve the puzzle by using X.Y in the extends clause of a type variable declaration:





public class FadeToBlack {

public static <T extends X.Y> void main(String[] args) {

System.out.println(T.Z);

}

}




In summary, to solve a problem caused by the obscuring of a type by a variable, rename the type and variable in accordance with standard naming conventions, as discussed in Puzzle 68. If this is not possible, use the obscured type name in a context where only type names are allowed. With any luck, you will never have to resort to such contortions, as most library authors are sane enough to avoid the questionable practices that make them necessary. If, however, you do find yourself in this situation, it's nice to know that there is a workaround.

















     < Day Day Up > 



    No comments: