为什么javac会抱怨泛型与类的类型参数无关? [英] Why does javac complain about generics unrelated to the class' type arguments?

查看:106
本文介绍了为什么javac会抱怨泛型与类的类型参数无关?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请仔细阅读代码中的注释,问题详情在那里。

为什么这种差异发生?

请引用JLS如果可能的话。

  import java.util。*; 

/ **
*假设我有一个泛型类
* @param< T>带有一个类型参数。
* /
class Generic< T> {
//除了正常使用T之外,
T paramMethod(){return null; }
//类的接口还包含通用Java集合
//它们不使用T,但是不相关的类型。
列表<整数> unrelatedMethod(){return null; }
}

@SuppressWarnings(unused)
public class Test {
//如果我正确使用类(带有限定类型参数)
void properUsage(){
Generic< String> g = new Generic< String>();

//一切正常。
String s = g.paramMethod();
列表<整数> pos = g.unrelatedMethod();

//确定错误:不兼容的类型:列表< String> := List< Integer>
列表< String> thisShouldErrorCompile = g.unrelatedMethod();
}

//但是当我使用原始类型时,* ALL *泛型支持消失了,甚至是Collections'。
void rawUsage(){
//使用泛型<?>随着类型轮换修复下面的警告。
Generic g = new Generic();

//确定错误:不兼容类型:String:= Object
String s = g.paramMethod();

// WTF警告:未经检查的转换:List< Integer> :=原始列表
列表<整数> pos = g.unrelatedMethod();

// WTF警告:未经检查的转换:列表< String> :=原始列表
列表< String> thisShouldErrorCompile = g.unrelatedMethod();


$ / code $ / pre
$ b

附注



我最初在IntelliJ IDEA中找到了这个,但我猜这个编译器与javac兼容,因为当我编译上面的代码时,它给出了相同的错误/警告。

  $ javac -version 
javac 1.7.0_05
$ javac Test.java -Xlint:未勾选
...
$ javac Test.java -Xlint:unchecked -source 1.5 -target 1.5
...


解决方案

From JLS 4.8原始类型


只允许使用原始类型作为遗留代码兼容性的让步。


使用泛型引入Java编程语言之后编写的代码中原始类型的使用是非常令人沮丧的。


构造函数的类型(§8.8),实例方法(§8.4,§9.4)或非静态字段(§8.3)未从其超类或超接口继承的原始类型C是对应于在对应于C的通用声明中删除其类型的原始类型。


其中 - 如果仔细阅读,则意味着所有类型都被擦除,而不仅仅是您遗漏的类型。


Please read the comments in the code in order, the question details are there.
Why is this difference happening?
Please quote the JLS if possible.

import java.util.*;

/**
 * Suppose I have a generic class
 * @param <T> with a type argument.
 */
class Generic<T> {
    // Apart from using T normally,
    T paramMethod() { return null; }
    // the class' interface also contains Generic Java Collections
    // which are not using T, but unrelated types.
    List<Integer> unrelatedMethod() { return null; }
}

@SuppressWarnings("unused")
public class Test {
    // If I use the class properly (with qualified type arguments)
    void properUsage() {
        Generic<String> g = new Generic<String>();

        // everything works fine.
        String s = g.paramMethod();
        List<Integer> pos = g.unrelatedMethod();

        // OK error: incompatible types: List<String> := List<Integer>
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }

    // But when I use the raw type, *ALL* the generics support is gone, even the Collections'.
    void rawUsage() {
        // Using Generic<?> as the type turns fixes the warnings below.
        Generic g = new Generic();

        // OK error: incompatible types: String := Object
        String s = g.paramMethod();

        // WTF warning: unchecked conversion: List<Integer> := raw List
        List<Integer> pos = g.unrelatedMethod();

        // WTF warning: unchecked conversion: List<String> := raw List
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }
}

Side note

I originally found this in IntelliJ IDEA, but I guess that compiler is compatible with javac because when I compiled the above code with the following it gave the same errors/warnings.

$ javac -version
javac 1.7.0_05
$ javac Test.java -Xlint:unchecked
...
$ javac Test.java -Xlint:unchecked -source 1.5 -target 1.5
...

解决方案

From JLS 4.8 Raw Types

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.

and

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

Which - if you read it carefully - implies that all types are erased, not just the type you left out.

这篇关于为什么javac会抱怨泛型与类的类型参数无关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆