问题描述
packagecom.test;publicclassTest2{publicstaticvoidmain(String[]args){methodA();}publicstaticvoidmethodA(){//行1Strings=null;//行2System.out.println(s.length());//这一行报一个警告:Nullpointeraccess:Thevariablescanonlybenullatthislocation}}疑问1:多个地方调用Test2类的methodA()方法,都是各自的methodA()方法,对吗?会互不影响,里面的局部变量s都会是各自的,对吗?为什么?在底层原理上如何解释?疑问2:为什么编译器只给出一个警告而不是错误呢?我认为用人为的方法也没有任何办法使在执行“行2”语句时s变量不为null,即是说:s变量一定为null,对吗?如果是这样,那编译器就应该报错,而不应该是警告啊,对吗?编译器为什么设计成只报警告而不是错误呢?是编译器做的粗糙不细的原因吗?下面还有一个例子,请注意看注释处,那里描述的是运行的结果:publicstaticvoidmain(String[]args){Listlist=newArrayList();list=null;for(Objects:list){//编译不报错,运行时,这行会报错:java.lang.NullPointerExceptionSystem.out.println(111111);}System.out.println(222222);}------------------------------------------疑问3:再看下面代码:packagecom.test;publicclassTest2{publicstaticvoidmain(String[]args){methodA();}publicstaticvoidmethodA(){Objecta=newInteger(3);//行1Strings=(String)a;//行2System.out.println(s);}}上面代码编译器没有报出任何的错误和警告。a变量中实际装的类型是Integer,到“行2”代码时,编译器一定能够有办法知道a变量中的实际类型,并且人为也没有任何办法使程序运行到“行2”时使a变量中的数据类型变成非Integer,因为这是在一个方法中,那么编译器为什么不在“行2”就报错呢?而使在运行时报了错?------------------------------------------疑问4:packagecom.test;publicclassTest3{publicstaticvoidmain(String[]args){inta=test();System.out.println(a);}privatestaticinttest(){inta=20/0;//行1System.out.println(a);//行2return0;}}上面代码,编译正常,没有报出任何的警告和错误,我的疑问:编译器为什么不在“行1”处报错误呢?而编译器是能够检测到这一行运行的时候一定会出错啊,我认为没有任何办法使“inta=20/0;”这行语句在运行时变化而使之不报错,对吗?那编译器为什么不使在编译的时候就使在“行1”处报错呢?
解决方案
解决方案二:
1、你这个说法有点小问题,methodA由于是static,所以永远只有一个,但是如果多个地方调用methodA,他们的运行环境确实是独立的不同的,也就是说有独立的栈内存,局部变量也当然是不同的,这个去看函数调用原理就知道了。234属于同一问题,这只是编译器设计上的问题,不同编译器表现可能不同,你完全可以自己写一个Java编译器检查所有明显错误的情况并报错不予以编译,或者你也可以写一个编译器完全不检查任何潜在错误。当前版本的官方编译器设计上认为编译器的本职工作只是编译,运行会不会出错和它无关,它在能编译通过的情况下尽量编译,除非是实在无法编译才会报告错误,如果它觉得这个代码可能有问题但可以编译通过,也只会警告,就算在你看来肯定会出错,编译器也是睁一只眼闭一只眼,这一方面是充分相信程序员,另一方面也是效率上的考虑,这类错误太多了,如果所有这些错误你都要去检查,并且做出适当处理,那开销太大,特别是大型项目编译,如果一个项目本来编译只需要一分钟,检查错误却要花上十分钟,那估计没有几个人会喜欢这个编译器,所以有些语言比如C/C++的某些编译器为了效率基本不会检查潜在错误。
解决方案三:
追问:疑问1中的代码:publicstaticvoidmethodA(){ //行1 Strings=null; //行2 System.out.println(s.length());}疑问5:想尽一切的办法,是否有方法能够使在执行“行2”代码时,使s变量的值不为null?我想过多线程,但也认为无法做到,因为这是一个方法,是一个方法中的局部变量,每个线程执行此方法,都会是 “各自单独” 地去执行此方法。