1.为什么方法里只要有while循环就可以不用返回值,而且必须是while,for循环就不行private String abc(){
        while(true){
        }
    }
2.jdk1.5开始增加了范型,为什么数组不支持范型,数组的范型检查警告该如何消除(请别说用@SuppressWarnings("unchecked"))
 
List[] listArray = new List[]{new ArrayList<String>(), new ArrayList<String>()};
listArray[0].add("0");
listArray[1].add("1");

解决方案 »

  1.   

    for也行,不懂,是不是因为死循环的缘故.
    public static String abc(){
            for(;true;){
            
            }
        }
      

  2.   

    1、首先,試了一下,for是可以的。其次,也不是说有while循环就不用返回值,而是死循环不用返回值,编译器还是比较聪明的。(可以试试看里面放个break)
    2、baidu了一下,IBM网站有篇文章,建议楼主去看看。
    大概的意思是:
    “在这里可以看到一种模式 —— 与泛型有关的很多问题或者折衷并非来自泛型本身,而是保持和已有代码兼容的要求带来的副作用。”
      

  3.   

    很有意思的问题
    如3,4楼所说,1可能是由于死循环引起的至于2
    LZ试下这段代码List<String>[] listArray = (ArrayList<String>[])new List[2];
    listArray[0].add("0");
    listArray[1].add("1");
      

  4.   

    试了一下5楼的代码,确实没有范型检查警告,不过运行时会发生类型转换异常
    除非改成List<String>[] listArray = (List<String>[])new List[2];但是范型检查警告又出来了
      

  5.   

    忘记贴网址了,这个是那篇文章
    http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
      

  6.   

    好像只能new Object数组然后强制转型成泛型数组
      

  7.   

    但是,如果按照4楼所说的,下面的代码怎么解释呢?这样会报错的,也是个死循环。public static String abc(){
        boolean b = true;
        while(b){    }
    }
      

  8.   

    会不会是编译器没法确定b就是true啊?
    虽然很明显,但是编译器可能只会认保留字true这个吧
      

  9.   

    编译很智能哦,他还能自动判断出是个死循环,所以根本就不要返回值.
    要是把while中的条件不直接用(true)而用变量表示,他就会提示错误。
    哈哈!
      

  10.   

    抛出异常后也不会要求返回值的(Eclipse上加了返回语句会提示错误):public String checkVal(int val) {
       if (val > 0) {
          return "valid";
       } else {
          throw new RuntimeException();
       }
    }
      

  11.   

    编译器毕竟不是虚拟机,它不是通过执行一个java文件来判断错误,
    使用了变量,虽然很明显上面是true,也是需要程序运行时才可能确定,编译时它只是个boolean类型的变量,什么也不代表java的异常机制分为已检查异常和未检查异常,这个RuntimeException是未检查异常,所以编译器是不会强制要求必须捕获的,
    同时它也知道如果抛出了这个异常,要么整个程序终止,要么由调用它的方法来捕获,这个方法是不可能再继续执行下去了,所以不需要返回值的。
    eclipse其实也是靠编译器提示出来的。 
    如果加上return的话就是Unreachable code,其实不管下面加什么,结果都是一样的。
      

  12.   

    回答 10 楼的问题:我认为应该是这样的:编译器能够静态识别出所有的 reachable branch。而你那段程序,并不能在编译期就判定为“死循环”,所以就报错了。我估计,如果你把 b 的定义改成 final boolean b = true; 应该就能编译通过了。我没试过,猜的 :)
      

  13.   

    15楼的说法似乎解释不通,将火龙果的代码做些修改就能通过了    public static String abc(){
            final boolean b = true;
            while(b){        }
        }虽然都是使用了b,但是编译器判断出不加final的b有可能被改变,所以是否形成死循环是不确定的,
    而加了final的b已经确定会造成死循环。将代码再做些修改    private static final boolean B = true;
        
        public static String abc(){
            final boolean b = B;        while(b){        }
        }同样证明了刚才的说法,将B的final去掉,或不进行初始化,B就会具有不确定性,无法造成死循环,因此出错将代码再做些修改    public static String abc(){
            final boolean b = getB();        while(b){        }
        }    private static boolean getB(){
            return true;
        }b由方法getB取得,getB是私有的,显然具有唯一性,返回的也是确定的true,那么按理b也应该是确定的,
    但遗憾的是编译器告诉我们abc需要返回值,也就是他判断的结果是b是不确定的,不知道是true还是false.我们再做些改变    public static String abc() {
            final boolean b = ClassB.BB;        while (b) {        }
        }    private class ClassB {
            private static final boolean BB = true;
        }这回b的值由ClassB的常量BB提供,编译通过了,将BB的final去掉或是不进行初始化都无法通过。
    看来编译器只能判断到常量字段,到了方法这一级别它就会认为具有不确定性。
      

  14.   

    因为你while(true)的时候,ide认为代码到这里就会看不到while下面的(没机会运行)所以也就不需要检查最终的返回
    你可以尝试 while(false) 看看ide会不会报错-- 这个不是java语法的问题
      

  15.   

    嗯,我的猜测有点问题,有可能像楼主说的那样正在看《深入Java虚拟机》,估计这样设计也是和虚拟机一样为了避免“停机问题”吧
      

  16.   

    TO:18楼你试试用javac自己编译一下,看看会不会报错。
    怎么能说“这个不是Java语法的问题”呢?
      

  17.   

    关于第二个问题,研究了一下Collection下的class,竟发现有无数的安全警告,
    看来这个问题连编写jdk的sun的技术者也无法解决,只能先这么摆着了。另外感谢angues1980石头心提供的资料,很实用的!并且期待你对虚拟机的研究成果。
      

  18.   

    研究了一下Collection下的class,竟发现有无数的安全警告
    _____________________________[size=30px]o(∩_∩)o 哈哈[/size]
      

  19.   

    研究了一下Collection下的class,竟发现有无数的安全警告 =============================
    深有同感
      

  20.   

    楼主好学的精神值得大家学习哦!第一个问题其实是基于一条简单的规则:JAVA不允许有编译器能确定的永远执行不到的语句(即使是return语句也不行!)。
    所以,这个问题不是“可以不返回值”,而是“不能返回”,也就是说,在死循环后面加上返回是错的,因为这里的返回语句是永远执行不到的。语句永远不被执行的情况有几种:出现在明确的死循环之后,出现在明确的return语句之后,出现在明确的异常抛出语句之后。
    这里的“明确的”意思是编译器可以确定的,基于这个规则,下面的代码都不能编译:int f() {
      return 0;
      System.out.println("never reach here!");  // won't compile!
    }int g() {
      while(true);  // or equally, for(;;) ;
      return 0;  // won't compile!
    }int h() {
      throw new RuntimeException();
      return 0;  // won't compile!
    }但是,编译器毕竟不是完全智能的,很多可以“明确”的情况下,它也可能置之不理。如if(true)后面的return语句和throw语句,有变量参与的死循环等等。编译器的职责是检查语法错误,而不是语义错误,JAVA编译器管得比较宽,但依赖编译器来检查语义错误总是不可取的。
      

  21.   

    第二个问题,改成下面这样就可以不出现安全警告了:List[] listArray = new List[]{new ArrayList<String>(), new ArrayList<String>()};
    ((ArrayList<String>)listArray[0]).add("0");
    ((ArrayList<String>)listArray[1]).add("1");
      

  22.   

    楼上回答的第二个问题是用向下转型消除了警告,表面上似乎是解决了,
    但如果我把写法改一下你又该如何转型呢?ArrayList[] listArray = new ArrayList[]{new ArrayList<String>(), new ArrayList<String>()};
      

  23.   

    呵呵,关于第二个问题,读了一下sun的官方文档,发现泛型的限制还是蛮多的。泛型只是一个编译时范畴,编译器在编译期间会对所有的泛型声明执行类型消除(Type Erasure ),也就是说,任何和运行时相关的操作都不支持泛型。只有编译器认识泛型,JVM根本不认识。所以泛型机制只是编译器方面的革新,泛型机制编译出来的字节码,并不需要一个所谓“支持泛型的JVM”来解释。
    数组的类型是需要在编译时确定的,所以,创建“泛型数组”就意味着要编译器把这个泛型对象留给JVM去解释,违背了“类型消除”的原则。所以,“泛型数组”是不存在的。
      

  24.   

    很多技术文章中提到了 oop和泛型中间有很多设计原则上的冲突。
      

  25.   


    自己再继承arraylist再转呗........
      

  26.   

        public static String abc(){
            final boolean b = getB();        while(b){        }
        }    private static boolean getB(){
            return true;
        }此段代码无法造成次循环 b还是不能确定的 为什么呢?