如何以及何时为java中的泛型方法解析类型?

时间:2014-10-14 11:01:16

标签: java generics methods

我希望跟随单元测试失败并使用 ClassCastException ,但是它的传递。

该类有一个泛型方法,其第二个参数和返回值的类型为V。

在第二次调用方法时,使用第二个参数V的类型作为Integer,返回类型应为Integer。但在运行时它实际上返回String值。

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

public class GenericMethodTest {

  private class NonGenericClass {

    private final Map<Object, Object> myMap = new HashMap<>();

    <K, V> V addGeneric(K key, V value) {

      V existingV = (V) myMap.get(key);
      // why no ClassCastException on this above line, when type of V is Integer, but myMap.get(key) returns value of
      // type String?

      if (existingV == null) {
        myMap.put(key, value);
        return value;
      }
      return existingV;
    }
  }

  @Test
  public void test() {
    NonGenericClass nonGenericClass = new NonGenericClass();

    nonGenericClass.addGeneric("One", "One");
    // String valueString = (String) nonGenericClass.addGeneric("One", Integer.valueOf(1));
    // Compiler error as expected, if above line uncommented - Cannot cast from Integer to String.

    // But no error at run-time, and below call returns value of type String.
    nonGenericClass.addGeneric("One", Integer.valueOf(1));
  }

}

1 个答案:

答案 0 :(得分:1)

这是由于类型擦除。基本上,KV的类型在执行时是未知的。未选中对V的强制转换 - 您应该在编译时收到警告(可能建议您使用-Xlint进行编译)。

如果您希望在执行时检查演员表,则需要相关的Class对象,此时您可以使用Class.cast进行检查。

有关详情,请参阅type erasure in the Java generics FAQ以及"Can I cast to a parameterized type?"