意外的未经检查的转换警告

Kon*_*hik 8 java generics

任何人都可以解释为什么在y分配线上有一个无类型的转换警告?请注意,x或z分配没有警告.

public class Entity<T>
{
    @SuppressWarnings("unchecked")
    public <TX> Entity<TX> typed( Class<TX> type )
    {
        return (Entity<TX>) this;
    }

    @SuppressWarnings("unchecked")
    public static <TX> Entity<TX> typed( Entity<?> entity,  Class<TX> type )
    {
        return (Entity<TX>) entity;
    }

    public static void main( final String[] args )
    {
        final Entity<?> a = new Entity<Integer>();
        final Entity b = (Entity) a;

        final Entity<Integer> x = a.typed( Integer.class );
        final Entity<Integer> y = b.typed( Integer.class );
        final Entity<Integer> z = typed( b, Integer.class );
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

b是类型Entity,这是一种原始类型.因此它的API看起来像这样:

public Entity typed(Class type)
Run Code Online (Sandbox Code Playgroud)

所以你要转变EntityEntity<Integer>.编译器丢失了type参数与返回的实体类型之间的任何关联,因此无法进行任何检查.

换句话说,你可以使用:

final Entity<Integer> y = b.typed(String.class);
Run Code Online (Sandbox Code Playgroud)

......并且仍然只收到相同的警告.如果您使用x或尝试相同的更改z,则会收到编译时错误.

编辑:如评论中所述,您使用原始类型的事实删除了所有泛型的痕迹.

JLS第4.8节:

为了便于与非泛型遗留代码接口,可以使用参数化类型(第4.5节)的擦除(第4.6节)或者数组类型为参数化类型的数组类型(第10.1节)的擦除作为类型. .这种类型称为原始类型.

然后在4.6节:

类型擦除还将构造函数或方法的签名(第8.4.2节)映射到没有参数化类型或类型变量的签名.构造函数或方法签名s的擦除是由与s相同的名称和s中给出的所有形式参数类型的擦除组成的签名.

  • @KonstantinKomissarchik:没关系 - 当你在原始类型上调用一个方法时,一切都消失了. (4认同)