yizishou 2015-06-02 10:43 采纳率: 100%
浏览 2754
已采纳

对于Java反射的安全性的一些疑问

最近在看深入理解JVM,随手写了一点代码,有个问题不太理解。
代码如下:

    public static void main(String[] args) throws Exception {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        Method put = HashMap.class.getMethod("put", Object.class, Object.class);
        put.invoke(map, 1, new Object());
        System.out.println(map);
        String val = map.get(1);
        System.out.println(val);
    }

执行结果(编译和执行版本都是1.6):

 {1=java.lang.Object@2e6e1408}
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
    at T002.main(T002.java:12)

报错是在String val = map.get(1);这一行。

我不解的是:
通过反射,Integer-Object键值对竟然正确地放进了Integer-String的HashMap中!

这种不合理的结果,应当是很严重的BUG了吧,但是也从没听谁提到过。

希望大家多多指点

  • 写回答

2条回答 默认 最新

  • threenewbee 2015-06-02 10:49
    关注

    另外java泛型的机制:
    http://irfen.iteye.com/blog/1888312

    Java泛型实现原理:类型擦出
           Java的泛型是伪泛型。在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(type erasure)。
           Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。
        如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方法与C++模版机制实现方式(后面介绍)之间的重要区别。 
    

    因为是编译完成的,包括类型检查这些,而反射绕过了编译检查,所以是没办法的。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP