CSDN=>FAQ=>FAQ 展示
  • 问题内容: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)
相关FAQ
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo