为什么第二个示例中没有任何编译错误,但第一个示例中存在以下编译错误?
SomeConcreateClass.java:1: ISomeBaseInterface cannot be inherited with different arguments: <java.lang.Object> and <>
public class SomeConcreateClass
^
1 error
唯一的区别 - 类SomeDerivedClass在第二个示例中未参数化。
例1:
我在这个例子中是否正确理解
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{}
class SomeDerivedClass<T> /* <-------*/
extends SomeAbstractClass<Object>
implements ISomeInterface
{}
abstract class SomeAbstractClass<T>
implements ISomeBaseInterface<T>
{}
interface ISomeInterface extends ISomeBaseInterface<Object>
{}
interface ISomeBaseInterface<T>
{}
示例2:
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{}
class SomeDerivedClass /* <-------*/
extends SomeAbstractClass<Object>
implements ISomeInterface
{}
abstract class SomeAbstractClass<T>
implements ISomeBaseInterface<T>
{}
interface ISomeInterface extends ISomeBaseInterface<Object>
{}
interface ISomeBaseInterface<T>
{}
更新
我是否正确理解,在下面的示例中,从SomeDerivedClass开始的所有树都将用作原始类型?
SomeBaseClass的第一个参数是List的信息将丢失
这是对的吗?
import java.util.List;
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{
public static void main(String[] args) {
SomeConcreateClass c = new SomeConcreateClass();
List lst = c.getT(); //Type mismatch: cannot convert from Object to List
}
}
class SomeDerivedClass<T>
extends SomeBaseClass<List, T> /* <----- */
implements ISomeInterface
{}
class SomeBaseClass<T, M>
implements ISomeBaseInterface<T>
{
public T getT(){return null;}
}
interface ISomeInterface extends ISomeBaseInterface<List>
{}
interface ISomeBaseInterface<T>
{}
答案 0 :(得分:3)
简而言之,使用原始类型(即使用不带类型参数的泛型类型)会禁用其背后的所有通用相关内容。
通常通过以下示例演示:
class Foo<T> { public List<String> m() { ... } }
String s1 = new Foo<Object>().m().get(0); // Compiles
String s2 = new Foo().m().get(0); // Cannot cast Object to String
你有类似的情况,但它与继承而不是成员访问有关。
以下是JLS 4.8 Raw Types的相关引用:
原始类型的超类(分别是超级接口)是其任何参数化调用的超类(超接口)的擦除。
在第一个示例中,SomeDerivedClass
是通用的,SomeConcreteClass
将其作为原始类型继承。因此,通过此继承分支继承的ISomeBaseInterface<Object>
变为其擦除ISomeBaseInterface<>
,但直接继承的ISomeInterface
仍然继承ISomeBaseInterface<Object>
。由于您无法使用不同的类型参数多次实现相同的通用接口,因此编译器会报告错误。
在第二个示例中,SomeDerivedClass
不是通用的,因此原始类型没有问题。