Java 如何正确使用参数中的泛型

Java 如何正确使用参数中的泛型,java,generics,Java,Generics,我现在有这个: public <T> void run(T x){ if(x instanceof HashMap){ ((HashMap<String,String>)x).put("foo","bar"); } } 但我看到这个警告: 我有三个问题: 有人知道这个警告是关于什么的吗? 我使用instanceof操作符对吗?是否有更好/更准确的检查方法可供使用? 是否有某种方法可以使用泛型,这样方法就知道类型是什么,这样我就

我现在有这个:

  public <T> void run(T x){

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

  }
但我看到这个警告:

我有三个问题:

有人知道这个警告是关于什么的吗? 我使用instanceof操作符对吗?是否有更好/更准确的检查方法可供使用? 是否有某种方法可以使用泛型,这样方法就知道类型是什么,这样我就不必强制转换类型了?
我不知道你想用你的方法达到什么目的

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中有一种称为类型擦除的东西,在这种情况下,泛型方法在运行时无法知道对象的类型。您可以传入类进行强制转换,或者需要使用有界通配符进行编译时检查。

此T可以是扩展对象的任何类型,并且您的代码不是类型安全的。如果传入HashMap以外的任何内容,您可能会得到ClassCastException。但使用操作符实例将防止这种情况发生。但任何人都可以向您的方法发送任何对象。因此,未经检查的警告只说明了这一点

对我来说,在这里使用“实例”似乎有点尴尬。相反,如果您想向现有映射添加一个条目,您可以像这样更改泛型方法的声明

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

此代码是类型安全的,比上述检查方法的实例更干净、更优雅。

您的方法的目标是什么,您可以传递的变量类型的期望是什么?正如所写,T是一个对象,无法进一步确定。未选中强制转换是由于将未知类型的对象强制转换为字符串到字符串的映射。您可以添加@SuppressWarningunchecked以隐藏警告,在这种情况下,您至少可以将其强制转换为HashMap,但您仍然不确定映射中包含哪些泛型类型,如果您传递了HashMap字符串Integer会怎么样?它是if块中的已知类型,对吗?您知道它是HashMap,但你不知道这是一个哈希图