具有内部类和内部接口的 Java 泛型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5402869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generics with inner class and inner interface
提问by Faton
Below I have a generic OuterClass, an InnerClass that use OuterClass generics and non-generic InnerInterface.
下面我有一个通用的 OuterClass,一个使用 OuterClass 泛型和非通用 InnerInterface 的 InnerClass。
public class OuterClass<E> {
public class InnerClass {
public E someMethod() {
return null;
}
}
public interface InnerInterface{
public void onEvent(OuterClass.InnerClass innerClass);
}
}
In the main method below, I use two instance of OuterClass, o1 parameterized with , and o2 with . My annonymous inner class myListener tries to use the generic type of the outer class (E). The code as it is below does not compile (Integer i = innerClass.someMethod() - Type mismatch: cannot convert from Object to Integer).
在下面的主要方法中,我使用了 OuterClass 的两个实例,o1 参数化为 ,o2 参数化为 。我的匿名内部类 myListener 尝试使用外部类 (E) 的泛型类型。下面的代码无法编译(Integer i = innerClass.someMethod() - Type mismatch: cannot convert from Object to 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();
}
};
}
}
I would like to express that myListener is for o1, and should use E = Integer, without repeating it (without repeating , I already say it when declaring o1). Is that possible?
我想表示 myListener 是针对 o1 的,应该使用 E = Integer,不重复(不重复,我在声明 o1 时已经说过了)。那可能吗?
Many thanks! Faton.
非常感谢!法顿。
回答by Laurent Pireyn
An inner interface or enum is implicitely static, and static members are not parameterized with the type parameters of the outer class. So InnerInterface
should look like this:
内部接口或枚举是隐式静态的,并且静态成员不会使用外部类的类型参数进行参数化。所以InnerInterface
应该是这样的:
public interface InnerInterface<E> {
void onEvent(OuterClass<E>.InnerClass innerClass);
}
Note that the E
parameter of InnerInterface
is notthe same as the E
parameter of OuterClass
.
注意E
的参数InnerInterface
是不一样E
的参数OuterClass
。
回答by Tom Hawtin - tackline
As always, non-private
nested types don't help keeping things simple. Push the boat out and create some new files, even if your IDe works against you.
与往常一样,非private
嵌套类型无助于保持简单。推开船并创建一些新文件,即使您的 IDe 对您不利。
Anyway, static members of a class do not share the generic parameters of the outer class. This is important for the behaviour of fields, and allows more flexibility on static nested types (such as InnerInterface
) even if you don't want it. So, in your case, you need to give your (static) nested interface a generic parameter. For $deity's sake, use a different identifier!
无论如何,类的静态成员不共享外部类的泛型参数。这对于字段的行为很重要,并且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();
}
};
}
}
(I've also qualified InnerClass
where necessary.)
(InnerClass
必要时我也有资格。)
Edit: It's probably worth just looking at the original anonymous inner class in isolation from the rest of the use:
编辑:将原始匿名内部类与其他用途分开查看可能是值得的:
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
only appears once, in a place where it clearly cannot be inferred to be correct.
Integer
只出现一次,在明显无法推断正确的地方。