2011-03-23 74 views
8

下面我有一個通用的OuterClass,一個使用OuterClass泛型和 非泛型InnerInterface的InnerClass。具有內部類和內部接口的Java泛型

public class OuterClass<E> { 

    public class InnerClass { 

     public E someMethod() { 
      return null; 
     } 
    } 

    public interface InnerInterface{ 
     public void onEvent(OuterClass.InnerClass innerClass); 
    } 
} 

在下面的主要方法中,我使用了OuterClass的兩個實例,o1用and2和o2參數化。 我的annonymous內部類myListener嘗試使用外部類(E)的泛型類型。 下面的代碼不會編譯(Integer i = innerClass.someMethod() - 類型不匹配:無法從Object轉換爲整數)。

public class Test { 
    public static void main(String[] args) { 

     OuterClass<Integer> o1 = new OuterClass<Integer>(); 
     OuterClass<String> o2 = new OuterClass<String>(); 

     OuterClass.InnerInterface innerInterface = new OuterClass.InnerInterface() { 
      @Override 
      public void onEvent(InnerClass innerClass) { 
       Integer i = innerClass.someMethod(); 
      } 
     }; 
    } 
} 

我想表達myListener的是O1,並應使用E =整數,而無需重複它(不重複,我已經說出來,宣佈01時)。那可能嗎?

非常感謝! Faton。

+0

您的接口方法也需要通用化。 – Bombe 2011-03-23 09:14:25

回答

13

內部接口或枚舉是隱式靜態的,並且靜態成員沒有使用外部類的類型參數進行參數化。所以InnerInterface應該是這樣的:

public interface InnerInterface<E> { 
    void onEvent(OuterClass<E>.InnerClass innerClass); 
} 

注意的InnerInterfaceE參數一樣的OuterClassE參數。

+8

也許那麼最好不要叫它E? – Ingo 2011-03-23 09:40:44

+2

謝謝洛朗。它會工作,但我必須重複,因爲它是一個不同的E.我的問題是「是否有可能重用第一個E = 」,並防止爲該接口重新聲明? – Faton 2011-03-23 09:48:04

+1

對泛型參數使用相同的標識符可能不是一個好主意。 – 2011-03-23 09:52:30

1

一如既往,非private嵌套類型不能幫助保持簡單。即使您的身份證與您不一致,也可以將小船推出並創建一些新文件。

無論如何,類的靜態成員不共享外部類的泛型參數。這對於字段的行爲很重要,並且允許靜態嵌套類型(例如InnerInterface)更靈活,即使您不需要它。所以,就你而言,你需要給你的(靜態)嵌套接口一個通用參數。爲了本尊,請使用不同的標識符!

public class OuterClass<E> { 
    public class InnerClass { 
     public E someMethod() { 
      return null; 
     } 
    } 

    public interface InnerInterface<T> { 
     void onEvent(OuterClass<T>.InnerClass innerClass); 
    } 
} 


public class Test { 
    public static void main(String[] args) { 

     OuterClass<Integer> o1 = new OuterClass<Integer>(); 
     OuterClass<String> o2 = new OuterClass<String>(); 

     OuterClass.InnerInterface<Integer> innerInterface = 
      new OuterClass.InnerInterface<Integer>() 
     { 
      @Override 
      public void onEvent(OuterClass<Integer>.InnerClass innerClass) { 
       Integer i = innerClass.someMethod(); 
      } 
     }; 
    } 
} 

(我也有資格InnerClass必要。)

編輯:這可能是值得只是孤立地看原來匿名內部類從使用的其餘部分:

public interface InnerInterface{ 
    public void onEvent(OuterClass.InnerClass innerClass); 
} 

    OuterClass.InnerInterface innerInterface = new OuterClass.InnerInterface() { 
     @Override 
     public void onEvent(InnerClass innerClass) { 
      Integer i = innerClass.someMethod(); 
     } 
    }; 

Integer只出現一次,在一個明顯無法推斷爲正確的地方。