2011-03-23 73 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只出现一次,在一个明显无法推断为正确的地方。