-
问题内容:Java Puzzlers里面的一个谜题,大家都给个解释,进者有分
- 原讨论链接:http://community.csdn.net/expert/topicview1.asp?id=4751639
- 所属论坛:J2SE / 基础类
审核组:JAVA
- 提问者:killme2008
解决者:foxty
- 感谢:huyc_fly huyc_fly fronm whulibo TinyJimmy foxty
- 关键字:变量 Java J2SE / 基础类 source unknown 局部 捕获 装入 missing strange2 strange1 糊涂
- 答案:
请考虑下面两个类:
//Strange1.java
public class Strange1 {
public static void main(String[] args) {
try {
Missing m = new Missing();
} catch (java.lang.NoClassDefFoundError ex) {
System.out.println("Got it!");
}
}
}
//Strange2.java
public class Strange2 {
public static void main(String[] args) {
Missing m;
try {
m = new Missing();
} catch (java.lang.NoClassDefFoundError ex) {
System.out.println("Got it!");
}
}
}
这两个类Strange1,Strange2都用到了下面的类:
//Missing.java
class Missing {
Missing() { }
}
如果你编译这3个类,然后在运行Strange1和Strange2之前删除Missing.class文件,你就会发现这两个程序的行为有所不同,其中一个抛出了一个未被捕获的NoClassDefFoundError异常,而另一个却打印了Got it!,到底是哪一个程序具有哪一种行为,你又如何去解释这种差异.
结果是:Strange1抛出了异常,Strange2打印了Got it!
书中的解释反而让我更糊涂,翻译的本来就不好,解释起来反而更糊涂了,大家都试试?发表下自己的看法.
---------------------------------------------------------------
我的执行结果怎么都一样?
D:\workspace\csdn\bin\camel>java Strange1
Exception in thread "main" java.lang.NoClassDefFoundError: Strange1 (wrong name:
camel/Strange1)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
D:\workspace\csdn\bin\camel>java Strange2
Exception in thread "main" java.lang.NoClassDefFoundError: Strange2 (wrong name:
camel/Strange2)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
---------------------------------------------------------------
NoClassDefFoundError这个是继承于java.lang.Error,这个是运行时错误,好像不能在程序中用try{}catch{}来捕获的吧?
ps.我的jdk是5.0
---------------------------------------------------------------
进来看看!
---------------------------------------------------------------
接分~~~
---------------------------------------------------------------
foxty(狐狸糊涂)
不是有Missing m这个声明,虚拟机就一定会将类Missing装载的. 如果Missing是一个接口或者抽象类, Missing不会被装入, 装入的只是Missing的实例对应的类而已. 现在的Strange2的Missing就是类似这样的情况
---------------------------------------------------------------
应该是这样吧,在Strange1中,变量m和异常ex都属于局部变量,而且2个的作用域是完全不冲突的,所以虚拟机就让这两个局部变量的地址共享了,在载入的时候需要验证公共超类。
但是在Strange2中,由于m是一个方法内的局部变量,而ex是catch块中的局部变量,m的作用域包含了ex的作用域,所以2个局部变量不能共享一个方法的局部变量区,自然在载入的时候就不需要验证公共超类了。
不知道这个说法是否正确,也是根据你贴出来的文字分析得来得,如果有误还望大家指正。
- 评价:
给朵鲜花(8)
扔个鸡蛋(0)