public class System{}public class test {
public static void main(String[] args) {
System.out.println("hello!");
}
}这个代码不能通过编译,因为自定义System遮蔽了java.lang包里的System,然而这和我看《深入JAVA虚拟机》中的双亲委派有所矛盾啊,按照双亲委派定义,当前AppClassloader要加载System类,必先问父加载器能不能找到,父加载器在问父直到所有父加载器全部没找到才加载当前的那这么说应该java.lang包里的System先加载阿,这么做的目的不也是为了防止恶意程序员用系统类库名称改写隐藏带攻击性的代码而么?

解决方案 »

  1.   

    public class System{}public class test {
        public static void main(String[] args) {
            java.lang.System.out.println("hello!");
        }
    }
      

  2.   

    1.有两个public class
    2.语法检查优先使用了你自定义的System,而你自定义的System类当然不能System.out改一改就能过编译了:class System
    {}public class test 
    {
      public static void main(String[] args) 
      {
        java.lang.System.out.println("hello!");
      }
    }
    这个类文件名是test喵~```
      

  3.   

    我找到问题所在了,这是源码兼容性与二进制兼容性概念混淆了,源码兼容的二进制一定兼容,二进制兼容的源码不一定兼容,这个例子就是二进制兼容而源码不兼容的例子,如果把两个类放在一起确实编译不了,编译不了就更运行不了,但是这个如果能通过编译就能正常运行,所以我先编译System再单独编译test,两个二进制文件放在一起能正常运行,并没有报找不到方法..所以双亲委派肯定没问题,我觉得编译器的验证规则是为虚拟机运行做提前筛选的,但是这里是编译器验证与虚拟机内运行机制不匹配导致的.
    比如设计一个系统能接受0~100之内数字,你想在前台验证不符合范围的连传都传不过来,然后验证数字必须在0~50中间,肯定没有问题,但是其实51传过来也不会有问题的..前台验证与服务器真是承受能力不匹配...
      

  4.   

    你自己定义的System中有out这个静态对象吗?你的问题我不太懂,不好意思!
      

  5.   

    这个是一个文件中写了两个public类,肯定不能通过编译.一个文件中只能有一个public类.分开编译当然是没有问题,因为系统的类是java.lang包下的.而你的是放在自己定义的包下.不会有冲突.还有java.lang包是自动隐式导入的,不需要自己显示的导入,所以可以用System.out.println("hello!")方法.并没有导入自己写的System类,也不产生冲突.如果用了两个重名的类不冲突才怪呢.不过楼主解释的太深噢了,不明白啊.也不知道楼主是想看什么样的效果呢.
      

  6.   

    我到网上查了一下,是一个很复杂的问题。
    虽然我不太清楚。
    我找了一点资料希望有帮助。
    http://www.blogjava.net/zhuxing/archive/2008/08/08/220841.html
      

  7.   


    没有,我要做的实验是自定义的System不会防碍对系统System的使用
      

  8.   

    一个java文件里只能有一个public class,并且要和java文件名完全相同
      

  9.   


    一,这不是一个文件,分明写在两个文件里的两个类
    二,按照道理说,这个程序不应该编译出错,因为即使定义的System类里没有out,那按照你说"java.lang包是自动隐式导入的"那编译器也应该去这个自动隐式包里去找有没有System里面存在out,而不该立刻就断定System类里没有out.编译器与虚拟机实际运行行为还是有不匹配的,因为明明如果编译通过就能正常运行,而编译器却认为这是错误而不通过编译.
      

  10.   

    汗,原来楼主在测试这个.这和双亲委派没有关系.编译器默认会为所有的类加上路径,你的System.out.println("hello!");
    这句在编译的时候被默认加上了louzhu.path.System的前缀,无法通过语法检测.实际运行没有报错,是因为System是JVM的顶级核心类,在JVM启动的时候被加载.
    因此所有同java.*下的类同名的类,都会被JVM视为无效,并为java.*的类顶替.与其说没有报错,不如说JVM把这个错误自动纠正了.如果拿其他类来做测试,就不会有这个问题了喵~~``
      

  11.   

    楼上的, 建议你还是用Eclipse之类的工具, 这种错误在Eclipse是可以提示的. 
    至于编译和虚拟机, 等你学会了使用工具再说了. 
    很多东西其实你不需要搞清楚内部她在做什么 只要知道他能做什么就OK了.
    何必搞得这么复杂, 你又不是要开发自己的java compiler.