2014-10-19 69 views
2
package generics; 
public class InnerClassGenerics{ 
    class Innerclasss{ 

    } 
    public static void main(String[] args) { 
     InnerClassGenerics icg=new InnerClassGenerics(); 
     Innerclasss innerclass=icg.new Innerclasss(); 
    } 
} 

上面的代碼是可能的,編譯好!是否可以使用參數化通用內部類?


爲什麼下面的代碼不能編譯,是否有可能參數化內部類?

package generics; 
public class InnerClassGenerics<T>{ 
    class Innerclasss<T>{ 

    } 
    public static void main(String[] args) { 
     InnerClassGenerics<String> icg=new InnerClassGenerics<>(); 
     Innerclasss<String> innerclass=new Innerclasss<>(); 
    } 
} 

在上面的代碼中,如果該類被製作爲靜態,它將正常工作! 爲什麼沒有靜態關鍵字是不可能的?

+1

這與泛型沒有任何關係,只是說。 – Smutje 2014-10-19 14:20:31

+0

[Java內部類和靜態嵌套類]的可能重複(http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class) – Smutje 2014-10-19 14:21:01

+0

您的類型參數''在內部類從外部階層隱藏''。無論如何,你應該改正你的例子(你試圖創建非靜態的內部類,而不使用任何外部類的實例)。 – Pshemo 2014-10-19 14:24:23

回答

4

一般來說,如果有也不會在外部類的任何泛型類型,你可以這樣寫代碼:

Outer outer = new Outer(); 
Inner inner = outer.new Inner(); 

因爲內部類每種方法已經知道它應該使用什麼類型的。

但是,當外部類使用泛型類型時情況稍微複雜一些。由於內部類可以訪問其外部類(或類)的所有成員,因此它還需要了解外部類中使用的泛型類型,以確保操作泛型值時的類型安全性。

看看這個代碼:

class Outer<T> { 
    private T someValue; 

    class Inner { 
     T getOuterValue(){ 
      return someValue; 
     } 
     void setOuterValue(T value){ 
      someValue=value; 
     } 
    } 
    //rest of code 
} 

這意味着Inner類的實例也取決於其外部類(ES)泛型類型。這就是爲什麼在創建參考,你需要寫它明確地使用與泛型類型外類作爲

Outer<String> outer = new Outer<>(); 
Outer<String>.Inner inner = outer.new Inner(); 
^^^^^^^^^^^^^ 

或明確地說,內部類是外部類使用raw type(不建議使用這種)像

Outer.Inner inner = outer.new Inner(); 

因此,爲了使你的代碼工作,你需要:

  1. 附加Ø子類的類型(最好與它的類型一致)

  2. 在外部類的實例上調用內部類的構造函數(就像非靜態方法不能在沒有實例的情況下被調用,必須創建非靜態(內部)類)使用外部類的實例)

    InnerClassGenerics<String>.Innerclasss<String> innerclass = icg.new Innerclasss<>(); 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^         ^^^^ 
         point 1           point 2 
    

你也不應該放棄在嵌套類相同的名字,以泛型類型和其外部類,像在這種情況下

public class InnerClassGenerics<T>{ 
    class Innerclasss<T>{ 
     ... 
    } 
} 

因爲TInnerclasss隱藏其外部類InnerClassGenericsT(不,它會導致當前的問題,但它可以讓你的生活困難後)。

+0

精確解釋..謝謝! – Terminator 2014-10-19 17:44:24

+0

@Terminator不客氣:) – Pshemo 2014-10-19 17:45:19

-1

所以你有這個類的定義,它不會編譯,因爲你有兩種類型叫T。使它像這樣,它會編譯:

public class OuterClass <O> 
{ 
    public class InnerClass <I> 
    { 
    } 
} 

另外,請注意,您正在實例靜態方法的非靜態類。你完成的代碼應該看起來像這樣:

public class OuterClass <O> 
{ 
    public static class InnerClass <I> 
    { 
    } 

    public OuterClass() 
    { 
    } 
    public InnerClass<O> getInnerClass() 
    { 
     return new InnerClass<O>(); 
    } 

    public static void main (String[] args) 
    { 
     OuterClass<String> outer = new OuterClass<>(); 
     InnerClass<String> inner = outer.getInnerClass(); 
    } 
} 

上面的代碼需要Java 8編譯。

+1

那麼,這可能是Java 7的一個問題,但InnerClass inner仍然會導致編譯器錯誤。它不應該是'OuterClass .InnerClass '? – Tom 2014-10-19 14:25:04

+0

@Tom在Java8(Eclipse)上編譯得很好 – msrd0 2014-10-19 14:26:39

+0

上面的代碼是拋出編譯時錯誤。 (無法對非靜態類型的InnerClass進行靜態引用) – Terminator 2014-10-19 14:29:13

相關問題