读书人

java解惑(谜题66。)

发布时间: 2012-12-20 09:53:21 作者: rapoo

java解惑(谜题66。。。)
谜题66:一件私事

class Base{public String className = "Base";}class Sub extends Base{private String className = "subclass";}public class PrivateMatter {public static void main(String[] args) {System.out.println(new Sub().className);}}

注意该程序有编译错误。因为子类中的变量比父类中的变量更具限制性的访问权限。而子类的变量是private,访问不了。尽管父类的变量被隐藏了,但是可以通过将子类实例转化为父类来访问它,如下可以打印出Base:System.out.println(((Base)new Sub()).className);
一旦一个方法在子类中被覆盖,你就不能在子类的实例上调用它了(除了在子类内部,通过使用super关键字的方法),然而,你可以通过将子类实例转化为父类来访问被隐藏的域。
谜题67:对字符串上瘾
public class StrungOut {public static void main(String[] args) {String s = new String("hello");System.out.println(s);}}class String{private final java.lang.String s;public String(java.lang.String s){this.s = s;}public java.lang.String toString(){return s;}}

运行会出现下图错误并报异常:java.lang.NoSuchMethodError: main



VM找不到main方法,是因为它并不在那里。一个main方法必须接受一个单一的字符串参数,而此程序中String是我们自己定义的String类,而非java.lang.String类。
谜题68:灰色的阴影
public class Shade {public static void main(String[] args) {System.out.println(X.Y.Z);}}class X{static class Y{static String Z = "Black";}static C Y = new C();}class C{String Z= "White";}

输出的是White。有一条规则决定着程序的行为,即当一个变量和一个类型具有相同的名字,并且它们位于相同的作用域时,变量名具有优先权。相似的,变量名和类型名可以遮掩包名。
注意:编程习惯,变量名小写,类名大写
谜题71:进口税
import static java.util.Arrays.toString;public class ImportDuty {public static void main(String[] args) {printArgs(1,2,3,4,5);} static void printArgs(Object...args) { System.out.println(toString(args));}}

编译错误,Arrays.toString(Object[])可以完全匹配,为啥出错呢?本例中toString引用的是Object继承而来的toString方法。简单地说,本身就属于某个范围的成员在该范围内与静态导入相比具有优先权。
可改为:
import  java.util.Arrays;public class ImportDuty {public static void main(String[] args) {printArgs(1,2,3,4,5);} static void printArgs(Object...args) { System.out.println(Arrays.toString(args)); //[1, 2, 3, 4, 5]}}


谜题:
class Base {public static final String PRIZE = "$64,000";}public class Sub extends Base {public static final String PRIZE = "2 cents";public static void main(String[] args) {System.out.println(Sub.PRIZE); // 2 cents}}

编译成功并打印出2 cents。
final修饰符对方法和域而言,意味着某些完全不同的事情。对于方法,final意味着该方法不能被覆写(对实例方法而言)或者隐藏(对静态方法而言)。对于域,final意味着该域不能被赋值超过一次。

读书人网 >编程

热点推荐