具有内部类和内部接口的Java泛型

具有内部类和内部接口的Java泛型,java,generics,Java,Generics,下面我有一个泛型OuterClass,一个使用OuterClass泛型和 非泛型内部接口 public class OuterClass<E> { public class InnerClass { public E someMethod() { return null; } } public interface InnerInterface{ public void onEven

下面我有一个泛型OuterClass,一个使用OuterClass泛型和 非泛型内部接口

public class OuterClass<E> {

    public class InnerClass  {

        public E someMethod() {
            return null;
        }
    }

    public interface InnerInterface{
        public void onEvent(OuterClass.InnerClass innerClass);
    }
}
公共类外部类{
公共类内部类{
公共E方法(){
返回null;
}
}
公共接口内部接口{
public void onEvent(OuterClass.InnerClass InnerClass);
}
}
在下面的主要方法中,我使用了OuterClass的两个实例,o1参数化为,o2参数化为。 我的annonymous内部类myListener尝试使用外部类(E)的泛型类型。 下面的代码未编译(整数i=innerClass.someMethod()-类型不匹配:无法从对象转换为整数)

公共类测试{
公共静态void main(字符串[]args){
OuterClass o1=新的OuterClass();
OuterClass o2=新的OuterClass();
OuterClass.InnerInterface InnerInterface=新的OuterClass.InnerInterface(){
@凌驾
public void onEvent(InnerClass InnerClass){
整数i=innerClass.someMethod();
}
};
}
}
我想表示myListener是用于o1的,应该使用E=Integer,而不重复它(不重复,我在声明o1时已经说过了)。可能吗

非常感谢!
Faton。

内部接口或枚举是隐式静态的,静态成员不使用外部类的类型参数进行参数化。因此,
InnerInterface
应该如下所示:

public interface InnerInterface<E> {
    void onEvent(OuterClass<E>.InnerClass innerClass);
}
公共接口内部接口{
void onEvent(OuterClass.InnerClass InnerClass);
}

请注意,
InnerInterface
E
参数与
OuterClass
E
参数不同,非
private
嵌套类型始终不能帮助保持简单。即使你的IDe对你不利,也要把船推出去并创建一些新文件

无论如何,类的静态成员不共享外部类的泛型参数。这对于字段的行为很重要,并允许在静态嵌套类型(例如
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();
            }
        };
    }
}

Integer
只出现一次,在一个明显无法推断其正确性的地方。

您的接口方法也需要泛化。那么,也许最好不要将其称为E?谢谢Laurent。这会起作用,但我必须重复,因为它是一个不同的E。我的问题是“是否可以重用第一个E=”,并防止重新声明接口?对于泛型参数使用相同的标识符可能不是一个好主意。@Faton那么答案是否。@Tom Maybe,但是
InnerInterface
的type参数与
Outerclass
E
具有非常相同的含义,我认为使用相同的名称可以使这种关系变得明显。
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();
            }
        };
    }
}
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();
        }
    };