相关疑难解决方法(0)

泛型奇怪 - 我可以在Map <String,String>中插入一个Long值,它会在运行时编译并且不会失败

提供以下代码:

public static void main(String[] args) {
        HashMap<String, String> hashMap = new HashMap<>();
        HashMap<String, Object> dataMap = new HashMap<>();
        dataMap.put("longvalue", 5L);

        class TestMethodHolder {
            <T> T getValue(Map<String, Object> dataMap, String value) {
                return (T)dataMap.get(value);
            }
        }

        hashMap.put("test", new TestMethodHolder().<String>getValue(dataMap, "longvalue"));
        String value = hashMap.get("test"); // ClassCastException occurs HERE
        System.out.println(value);
    }
Run Code Online (Sandbox Code Playgroud)

我编译这段代码并不奇怪,而是ClassCastException出现在get行上而不是它上面的put行,尽管我确实有一个有根据的猜测,可能会发生什么.由于泛型类型在运行时被擦除,因此getValue()中的强制转换实际上永远不会在运行时发生,并且实际上是对Object的强制转换.如果该方法将在下面实现如下,那么将发生运行时强制转换并且它将在put行上失败(如预期的那样).谁能证实这一点?

class TestMethodHolder {
        String getValue(Map<String, Object> dataMap, String value) {
            return (String)dataMap.get(value);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是使用泛型的已知缺陷还是奇怪?那么在调用方法时使用<>表示法是不好的做法?

编辑:我使用的是默认的Oracle JDK 1.7_03.

上面提到的另一个隐含问题:原始getValue STILL中的强制转换是在运行时发生的,但是强制转换实际上是对象 - 或者编译器是否足够聪明,以便在运行时不会发生此强制转换?这可能解释了人们在运行时注意到ClassCastException发生的位置的差异.

java generics

14
推荐指数
2
解决办法
709
查看次数

标签 统计

generics ×1

java ×1