2009-04-21 84 views
5

命名爲local classes很少使用,通常本地類是匿名的。有誰知道爲什麼下面的代碼會生成編譯器警告?Java - 本地類和泛型,爲什麼編譯器警告?

public class Stuff<E> { 
    Iterator<E> foo() { 
    class InIterator implements Iterator<E> { 
     @Override public boolean hasNext() { return false; } 
     @Override public E next() { return null; } 
     @Override public void remove() { } 
    } 
    return new InIterator(); 
    } 
} 

警告是new InIterator()和它說

[unchecked] unchecked conversion 
found : InIterator 
required: java.util.Iterator<E> 

如果類,不變的,是由匿名,或者如果它是由一個成員,警告消失。但是,作爲已命名的本地班級,它需要聲明class InIterator<E> implements ...以使警告消失。

發生了什麼事?

+0

只是出於好奇,我的編譯器不會抱怨這個警告......您使用的是什麼JVM? – 2009-04-21 14:57:06

+0

Sun Java 6更新12 – Yardena 2009-04-21 15:54:49

回答

1

我現在確信這是一個javac錯誤。上面給InIterator添加一個通用參數的方法隱藏或替換E是沒有用的,因爲它們排除了迭代器做一些有用的事情,比如返回一個類型爲E的東西的東西的E的元素。

然而,這編譯與沒有警告(感謝Jorn的提示):

public class Stuff<E> { 
    E bar; 
    Iterator<E> foo() { 
    class InIterator<Z> implements Iterator<E> { 
     @Override public boolean hasNext() { return false; } 
     @Override public E next() { return bar; } 
     @Override public void remove() { } 
    } 
    return new InIterator<Void>(); 
    } 
} 

絕對是一個錯誤。

3

我相信發生了什麼是你忽略了泛型類型參數,命名InIterator而沒有引用簽名中的泛型(即使它存在於接口中)。

這屬於愚蠢的編譯器警告類別:您已編寫該類,以便100%的實例將實現Iterator<E>,但編譯器無法識別它。 (我想這取決於編譯器,我沒有看到我的Eclipse編譯器中的警告,但我知道Eclipse編譯器處理的泛型與JDK編譯器略有不同)。我認爲這不太清楚,少接近你的意思,但也許更友好的編譯器,並最終相當於:

public class Stuff<E> { 
    Iterator<E> foo() { 
    class InIterator<F> implements Iterator<F> { 
     @Override public boolean hasNext() { return false; } 
     @Override public E next() { return null; } 
     @Override public void remove() { } 
    } 
    return new InIterator<E>(); 
    } 
} 
+0

謝謝大衛。 IntelliJ IDEA也沒有顯示任何警告,只是Sun javac。我知道如何解決這個問題,我只是想知道這種編譯器行爲是否存在一些奇怪而合法的原因,或者它是一個錯誤。 – Yardena 2009-04-21 15:01:36

+0

啊,IDE和javac編譯器之間的差異......這怎麼討厭:( – Jorn 2009-04-21 15:24:06

1

嗯,這裏沒有任何警告。

import java.util.Iterator; 

public class Stuff<E> { 
    Iterator<E> foo() { 
     class InIterator implements Iterator<E> { 
      public boolean hasNext() { 
       return false; 
      } 

      public E next() { 
       return null; 
      } 

      public void remove() { 
      } 
     } 
     return new InIterator(); 
    } 

    public static void main(String[] args) { 
     Iterator<String> i = new Stuff<String>().foo(); 
    } 
} 
1

是的,我也同意這應該是一個錯誤。如果你將本地類從方法中「提升」到成員類中,它也可以正常工作。除了不同的範圍和局部變量之外,兩者之間沒有太大的區別。

public class Stuff<E> { 
    class InIterator implements Iterator<E> { 
    @Override public boolean hasNext() { return false; } 
    @Override public E next() { return null; } 
    @Override public void remove() { } 
    } 
    Iterator<E> foo() { 
    return new InIterator(); 
    } 
}