英文:
Java Generics - Why returning super class instance gives compile error
问题
class SomeClass <T extends BaseClass> {
T method(T x) {
return x; // OK
}
T method() {
return new BaseClass(); // compile error
}
}
错误提示为需要 T
,但提供了 BaseClass
。
class SomeClass {
<T extends BaseClass> T method(T x) {
return x; // OK
}
<T extends BaseClass> T method() {
return new BaseClass(); // compile error
}
}
同样地,这段代码也会报错。
可以这样解决:
class SomeClass <T extends BaseClass> {
T method(T x) {
return x; // OK
}
@SuppressWarnings("unchecked")
T method() {
return (T) new BaseClass(); // OK
}
}
以下是为什么不允许这样的解释:
这个问题涉及到 Java 泛型的类型擦除(Type Erasure)。在 Java 中,泛型是在编译时进行类型检查的,而在运行时会将泛型类型擦除,以便与旧版本的 Java 代码兼容。在编译后的字节码中,泛型类型信息被移除,所以编译器无法确定在返回语句中的具体类型。
在第一个代码示例中,T
是一个泛型类型参数,它被限定为必须是 BaseClass
的子类。在 method()
中,您尝试返回一个新的 BaseClass
实例,但是在类型擦除后,编译器无法确定返回值的类型是否与泛型参数匹配。因此,编译器会报错,指出需要类型 T
,但实际提供的是 BaseClass
类型。
同样地,在第二个代码示例中,您在方法签名中引入了泛型类型参数 <T extends BaseClass>
,但是在返回语句中尝试返回一个新的 BaseClass
实例。由于类型擦除,编译器无法保证返回的类型与泛型参数相匹配,因此会报错。
您提供的解决方法利用了强制类型转换来绕过编译器的检查。然而,这也会带来风险,因为编译器无法验证强制转换是否安全。通常情况下,推荐避免这种情况,以避免在运行时出现类型转换异常。
希望这些解释对您有所帮助!
英文:
Hi the following code gives compile error but I do not understand why.
class SomeClass <T extends BaseClass> {
T method(T x) {
return x; // OK
}
T method() {
return new BaseClass(); // compile error
}
}
The error says requires T
but provided BaseClass
.<br>
And similarly this one:
class SomeClass {
<T extends BaseClass> T method(T x) {
return x; // OK
}
<T extends BaseClass> T method() {
return new BaseClass(); // compile error
}
}
I know that it can be resolved like this:
class SomeClass <T extends BaseClass> {
T method(T x) {
return x; // OK
}
@SuppressWarnings( "unchecked" )
T method() {
return (T) new BaseClass(); // OK
}
}
But may I have some explanation on why this is not allow?
答案1
得分: 3
这就是继承的工作原理。假设你有一个超类 A,它有子类 B 和 C。现在想象一下,你的方法接受一个类型为 A 的参数,并返回一个类型为 B 的对象。你的方法会接受类型为 C 的对象作为参数,但不能返回它们,因为它们不是类型为 B,尽管 B 和 C 都是 A 的子类。
英文:
That's just how inheritance works. Say you have a superclass A, and it has subclasses B and C. Now imagine your method accepts a parameter of type A and returns an object of type B. Your method would accept objects of type C as a parameter, but you couldn't return them because they are not of type B, even though both B and C are subclasses of A.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论