如何在参数中正确使用泛型

时间:2019-02-22 04:39:02

标签: java generics

我现在有这个:

  public <T> void run(T x){

    if(x instanceof HashMap){
      ((HashMap<String,String>)x).put("foo","bar");
    }

  }

但我看到此警告:

enter image description here

我有三个问题:

  1. 有人知道该警告是关于什么的吗?
  2. 我使用instanceof运算符对吗?有更好/更准确的检查方法可以使用吗?
  3. 是否有某种使用泛型的方法,以便该方法“知道”类型是什么,所以我不必强制转换类型?

2 个答案:

答案 0 :(得分:2)

T可以是扩展Object的任何类型,并且您的代码类型不安全。如果传递了HashMap<String, String>以外的任何内容,您可能会得到ClassCastException。但是使用instance of运算符可以防止这种情况的发生。但是仍然任何人都可以将任何对象发送到您的方法。因此,未经检查的警告仅说明了这一点。

在这里使用实例的实例对我来说有点尴尬。相反,如果要向现有地图添加条目,则可以像这样更改通用方法的声明,

public <S, T extends Map<S, S>> void addEntryToMap(T x, S key, S value) {
    x.put(key, value);
}

此代码比上面的check方法实例更安全,更简洁,更美观。

答案 1 :(得分:1)

我不确定您要在方法中实现什么

public <T> void run(T x){ // Gets an unbounded T which means it can accept anything under Object.

    if(x instanceof HashMap){
      ((HashMap<String,String>)x).put("foo","bar"); // How are you so sure it is an HashMap<String,String>? It can be any HashMap,or even Object!! That is exactly why your compiler is telling it is doing an unchecked cast.
    }
  }

这回答了您的第一点。

第二点,我们需要对此进行更清晰的说明。

第三点,Java中有一种称为类型擦除的类型,其中通用方法将无法在运行时知道对象的类型。您可以传递类进行转换,也可以使用有界通配符进行编译时检查。