简体   繁体   English

为什么超类通用类型不被擦除/铸造

[英]Why super classes generic type not erased/casted

Consider the following piece of code: 考虑以下代码:

class A<T>{
T t;

public T getValue(){
    return t;
}

class B<S extends Number> extends A<String>{

//some code here..
}

B b = new B<Integer>();
String name = b.getValue() // This throws compilation error

whereas the following works: 而以下作品:

B<Integer> b = new B<Integer>();
String name = b.getValue() // This works...!

So my questions are: 所以我的问题是:

  1. Do I have to give declare all the generics type involved? 我是否必须声明所有涉及的泛型类型? (Even though Class A's generic type was declared in Class B.) (即使在B类中声明了A类的泛型类型。)

  2. Or, am I missing something basically? 或者,我基本上是缺少什么吗?

See JLS 4.8 Raw Types : 请参阅JLS 4.8原始类型

a raw type is defined to be [...] the reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list. 原始类型被定义为通过采用通用类型声明的名称而没有附带的类型参数列表而形成的引用类型。

The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations. 原始类型的超类(分别是超接口)是其任何参数化调用的超类(超接口)的擦除。

In other words, when you use B without <> , it becomes a raw type, basically erasing all generics, all the way up all base classes and interfaces, ie is becomes as if A and B weren't generic: 换句话说,当您使用不带<> B时,它将成为原始类型,基本上擦除所有泛型,直至所有基类和接口,即好像AB不是泛型的:

class A {
    Object t;
    public Object getValue() {
        return t;
    }
}

class B extends A {
    //some code here..
}

Which is why String name = b.getValue() fails, because getValue() is now returning an Object . 这就是String name = b.getValue()失败的原因,因为getValue()现在返回一个Object


Note the following comment in the JLS: 请注意JLS中的以下注释:

The use of raw types is allowed only as a concession to compatibility of legacy code. 仅允许使用原始类型作为对遗留代码兼容性的让步。 The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged . 强烈建议不要在将泛型引入Java编程语言后在代码中使用原始类型 It is possible that future versions of the Java programming language will disallow the use of raw types. Java编程语言的未来版本可能会禁止使用原始类型。

In short, DON'T . 简而言之, 不要 Fix your code to not use raw types. 修复您的代码以不使用原始类型。

You can however shorten the right-hand side as follows: 但是,您可以按如下所示缩短右侧:

B<Integer> b = new B<>();

The generic value of class B simply has no link with the one from class A. B类的通用值与A类的值没有任何链接。

The method T getValue() of a A(Long) will be Long getValue(), disregarding any genericity on the wrapping class. A(Long)的方法T getValue()将是Long getValue(),而不考虑包装类上的任何泛型。

If you want an Integer getValue() then simply go for 如果您想要一个整数getValue(),那么只需

class B extends A<Integer> {}

EDIT : you change your question, lets change the response :) 编辑:您更改您的问题,让我们更改响应:)

B is considered as B (S extends Number, T) (because it extends A). B被认为是B(S扩展Number,T)(因为它扩展了A)。 If you store a variable as a raw type B, then its is implicitly B(Object, Object), even if declared properly. 如果将变量存储为原始类型B,则即使声明正确,其隐式也是B(Object,Object)。

Make test with a List 用清单进行测试

List l = new ArrayList<String>();
String s = l.get(0);

You will end with the same issue. 您将遇到同样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在 Java 中没有删除成员字段的此通用类型信息? - Why is this generic type information for member field not erased in Java? Android - 为什么对象被转换为类? - Android - Why are objects casted to Classes? 基于java中的超类和子类的泛型类型的多个限制 - Multiple restrictions on generic type based on super and sub classes in java 为什么在 Java 的类型转换期间允许在右侧使用(已擦除)泛型类型? - Why is usage of the (erased) generic type in right-hand side allowed during type casting in Java? 泛型类中擦除了所有HashMap类型值? - All HashMap type values erased in generic class? Java通用成员类型在子类中删除了? - Java Generic member type erased in subclass? 为什么超类字段的泛型类型不会被擦除到子类型的具体绑定中? - Why does the generic type of a superclass field not get erased to the concrete bound in a subtype? 当Java 8中的方法参数未经检查转换时,为什么会删除返回类型的泛型? - Why is generic of a return type erased when there is an unchecked conversion of a method parameter in Java 8? 为什么泛型类型不适用于两者的参数扩展超类? - Why generic type is not applicable for argument extends super class for both? 为什么在运行时Java中没有删除所有类型信息? - Why are not all type information erased in Java at runtime?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM