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.
No comments:
Post a Comment
Your comments are welcome!