【问题标题】:Java generic class cast exception thrown outsideJava泛型类转换异常抛出外部
【发布时间】:2017-11-15 21:18:23
【问题描述】:

当我执行此操作时,我在第 9 行得到一个 ClassCastException。我想知道为什么那里会发生异常。根据我对泛型的了解,我希望类型推断会导致在 try catch 中抛出异常。

这是使用 1.7 编译的。

public class MyClass {
    private static Map<String, Object> map = new HashMap<>();

    public static void main(String args[]) {
        map.put("key", Integer.valueOf(1));
        Float c = method("key");
    }

    public static <T> T method(String k) {
        try {
            return (T) map.get(k);
        } catch (ClassCastException ex) {
            System.out.println(ex);
            return null;
        }
    }
}

有什么方法可以在方法中抛出异常?我在下面看到了用法,但在调用时我无权访问 Float.class。

method(Float.class, "key")

public static <T> T method(Class<T> clazz, String k) {
    try {
        return clazz.cast(map.get(k));
...

【问题讨论】:

  • 你的意思是你没有访问 Float.class 的权限?您已经将 c 定义为 Float 类型。
  • 在我的实现中它将是 T c = method("key") 其中 T 确定了许多方法调用。
  • 那你为什么不把Class 对象从你实际上期望具体类型的顶部调用中传递出去?
  • 这是我想避免的。
  • 也许您可以将Class 放在顶级调用的本地线程中并在您的method 中获取它?

标签: java generics


【解决方案1】:

这是因为type erasure

实际上你的擦除后的代码会是这样的:

public static void main(String args[]) {
    map.put("key", Integer.valueOf(1));
    Float c = (Float) method("key");
}

public static Object method(String k) {
    try {
        return map.get(k);
    } catch (ClassCastException ex) {
        System.out.println(ex);
        return null;
    }
}

这就是为什么你在你没有预料到的一行中遇到了异常。

UPD:看来您必须使用反射来检查返回对象的实际类型。

【讨论】:

  • 在这种情况下擦除如何工作?我认为return (T)map.get(k) 会被类型擦除为return (Float)map.get(k),因为它可以从返回值中推断出来。
  • 此答案包含指向一篇非常好的文章的链接:stackoverflow.com/a/4590006/3323777 有一种解决方法可以保留类型信息。不确定它是否适合您的情况,请查看。答案本身很好地解释了擦除。
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多