【问题标题】:How and when the type gets resolved for generic methods in java?java中泛型方法的类型如何以及何时解析?
【发布时间】:2014-10-14 11:01:15
【问题描述】:

我预计后续单元测试会因 ClassCastException 而失败,但它会通过。

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

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

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));
  }

}

【问题讨论】:

    标签: java generics methods


    【解决方案1】:

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

    如果您想在执行时检查强制转换,您需要相关的Class 对象,此时您可以使用Class.cast 进行检查。

    更多信息请参见type erasure in the Java generics FAQ,以及"Can I cast to a parameterized type?"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-15
      • 2014-07-14
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多