Java 未选中的分配警告

Java 未选中的分配警告,java,generics,type-erasure,unchecked,raw-types,Java,Generics,Type Erasure,Unchecked,Raw Types,我正在使用Android Studio 1.1.0 这不会引起任何警告: public static class A { public Map<Integer, String> getMap() { return null; } } public static class B { public void processA(A a) { Map<Integer, String> map = a.getMap();

我正在使用Android Studio 1.1.0

这不会引起任何警告:

public static class A {
    public Map<Integer, String> getMap() {
        return null;
    }
}

public static class B {
    public void processA(A a) {
        Map<Integer, String> map = a.getMap();
    }
}
这一行:

Map<Integer, String> map = a.getMap();
但我为什么要这么做?
T
在这里有什么关系


因此,问题是-为什么类型擦除不仅要影响
T
(这是可以理解的-如果我传递
A
的实例,
T
是未知的),而且在这种情况下还要影响像
这样的“硬编码”通用签名?

当您打算接受任何可能类型的
A
时,但是不需要
t
,这可以通过使用通配符并写入
a
来正确表示。这样做将消除代码中的警告:

public void processA(A<?> a) {
    Map<Integer, String> map = a.getMap();
}
公共作废流程A(A){
Map Map=a.getMap();
}
使用裸类型
A
不会得到同等对待。如中所述,这样的原始类型不打算在新代码中使用:

未经检查的转换用于实现在引入泛型类型之前编写的遗留代码与经过转换以使用泛型(我们称之为泛型化)的库之间的平滑互操作。在这种情况下(最明显的是java.util中Collections框架的客户端),遗留代码使用原始类型(例如Collection而不是Collection)。原始类型的表达式作为参数传递给库方法,库方法使用这些类型的参数化版本作为其相应形式参数的类型

在使用泛型的类型系统下,这样的调用不能显示为静态安全的。拒绝此类调用将使大量现有代码无效,并阻止它们使用较新版本的库。这反过来又会阻碍图书馆供应商利用通用性。为了防止这种不受欢迎的事件转变,可以将原始类型转换为对原始类型所引用的泛型类型声明的任意调用。虽然这种转换是不合理的,但作为对实用性的让步是可以容忍的。在这种情况下会发出未经检查的警告


在第二种情况下,当您执行以下操作时:

public void processA(A a)
你所说的
A
是什么意思?它的意思是
A
A
还是什么?您可能没有使用任何与
A
类型相关的内容,但是编译器不知道这一事实。对编译器来说,只要
A
就是恐慌的信号

在您的情况下,因为您不需要特别了解A的类型,您可以:

public void processA(A<?> a) {
    Map<Integer, String> map = a.getMap();
} 
公共作废流程A(A){
Map Map=a.getMap();
} 
参数类型为
A
意味着,您并不特别关心
A
的类型,只需指定通配符即可。对你来说,它意味着:一个具有任何类型的
A
的任何对象,就像它的泛型类型一样。实际上,这意味着你不知道类型。它是无用的,因为你不能以类型安全的方式做任何与
A
相关的事情,因为
实际上可以是任何东西


但是根据你的方法体,在世界上使用
A
是很有意义的,因为在体中没有任何地方你真正需要
A的类型,你可能没有使用任何与A的类型相关的东西,但是嘿,编译器不知道这个事实
-好吧,它可以很容易地知道它,只要看看
processA
的实现,就不难验证
T
是否无关;)我会按照你的建议使用
,但我对编译器很失望。@KonradMorawski在理想的世界里,只要
A
应该是非法的,代码不应该编译。但由于向后兼容的原因,它是允许的。对于声明为
a
的类,其泛型类型对于执行与
a
相关的任何操作都非常重要。所以不应该只使用
A
(事实上,在Scala中,只使用
A
是非法的)是的,我想。。。我不使用Scala,但我来自世界的C#端,Java的泛型让人觉得穿鞋太小了。@KonradMorawski而且编译器几乎不可能知道它。你可能在做反思或者做演员,然后一起工作。很明显,要100%确信地表示没有使用这种字体是非常困难的。@Jatin-谢谢你的回答。这是对通配符的第一个解释,对我来说很有意义。(可能是因为我遇到了发问者的问题,我有一个带有显式参数化方法的参数化类,它警告在使用时有未经检查的赋值。)
public void processA(A a)
public void processA(A<?> a) {
    Map<Integer, String> map = a.getMap();
}