我发现了奇怪的泛型行为。用两个词 - 我真正想要的是以最常见的方式使用ComplexObject1,而我真正错过的是为什么定义泛型类型(... extends BuisnessObject)丢失了。 我的博客中也讨论了讨论主题 http://pronicles.blogspot.com/2010/03/unexpected-generics-behaviour.html
public class Test {
public interface EntityObject {}
public interface SomeInterface {}
public class BasicEntity implements EntityObject {}
public interface BuisnessObject<E extends EntityObject> {
E getEntity();
}
public interface ComplexObject1<V extends SomeInterface> extends BuisnessObject<BasicEntity> {}
public interface ComplexObject2 extends BuisnessObject<BasicEntity> {}
public void test(){
ComplexObject1 complexObject1 = null;
ComplexObject2 complexObject2 = null;
EntityObject entityObject1 = complexObject1.getEntity();
//BasicEntity entityObject1 = complexObject1.getEntity(); wtf incompatible types!!!!
BasicEntity basicEntity = complexObject2.getEntity();
}
}
答案 0 :(得分:2)
您的问题是您使用的原始类型ComplexObject1
。它很容易修复:只需使用ComplexObject1<?>
,您的代码编译就可以了。
这种行为真的没什么意外。
来自tutorial:
存在类型擦除,以便新代码可以继续与遗留代码接口。 出于任何其他原因使用原始类型被认为是糟糕的编程习惯,应尽可能避免使用。
来自JLS 4.8 Raw Types(强调他们的):
原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型。 未来版本的Java编程语言可能会禁止使用原始类型。
另请参阅 Effective Java 2nd Edition ,第23项:不要在新代码中使用原始类型。
答案 1 :(得分:1)
基本上,如果一个类具有泛型参数,并且在没有这些参数的情况下声明它,则它是一个原始类型。原始类型会在其成员中丢失泛型参数。
什么是原始类型?
没有任何类型参数的泛型类型。
没有任何类型的泛型类型 参数,如
Collection
,是 叫原始类型。
和Can I use a raw type like any other type?
原始类型的方法或构造函数 有他们的签名 有类型擦除后。
这使得人们陷入困境。例如:
public interface MyClass<T> {
T foo();
List<String> bar();
}
MyClass m = ...
List<String> list = m.bar(); // warning!
它让人感到困惑,因为此方法的返回类型与泛型类型参数无关,但这就是Java的工作方式。