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

时间:2011-03-23 09:04:40

标签: java generics

下面我有一个通用的OuterClass,一个使用OuterClass泛型的InnerClass 非通用的InnerInterface。

public class OuterClass<E> {

    public class InnerClass  {

        public E someMethod() {
            return null;
        }
    }

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

在下面的主要方法中,我使用两个OuterClass实例,o1参数化,和o2一起使用。 我的匿名内部类myListener尝试使用外部类(E)的泛型类型。 下面的代码不能编译(Integer i = innerClass.someMethod() - 类型不匹配:无法从Object转换为Integer)。

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 = Integer,而不重复它(不重复,我在声明o1时已经说过了)。这可能吗?

非常感谢! Faton。

2 个答案:

答案 0 :(得分:15)

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

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

请注意,E的{​​{1}}参数InnerInterface的{​​{1}}参数相同。

答案 1 :(得分:1)

与往常一样,非private嵌套类型无助于保持简单。将船推出并创建一些新文件,即使您的IDe对您不利。

无论如何,类的静态成员不共享外部类的泛型参数。这对于字段的行为很重要,并且即使您不想要它,也可以在静态嵌套类型(例如InnerInterface)上提供更大的灵活性。因此,在您的情况下,您需要为(静态)嵌套接口提供通用参数。为了$ deity,请使用不同的标识符!

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只会出现一次,显然无法推断它是正确的。