故事背景
《互换身体》是由环球影业发行的喜剧电影, 于 2011 年 8 月 5 日在美国上映. 该片由大卫. 道金执导, 瑞安. 雷诺兹, 杰森. 贝特曼, 奥利维亚. 王尔德等主演. 该片讲述了一位居家好男人和一位蜂蝶浪子分别厌倦了自己的生活, 于是在某种神秘力量的辅助下两人互换身体与生活的故事.
大话西游: 紫霞和八戒互换了身体, 欲和至尊宝亲热, 结果直接吐了
java 的换身术
java 中也可以实现神奇的魔法, 比如把 String 放入 List<Integer > 或者把 Integer 放入 List<String>. 请看:
- public static void main(String[] args) {
- ArrayList<Integer> list = new ArrayList<Integer>();
- list.add(1);
- list.add(2);
- list.add(3);
- try {
- list.getClass().getMethod("add", Object.class).invoke(list, "www");
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
- | SecurityException e) {
- e.printStackTrace();
- }
- for (int i = 0; i <list.size(); i++) {
- System.out.println(list.get(i));
- }
- }
打印出的结果为:
1
2
3
www
震惊了吗? 整数的 list 里面竟然有字符串!!!
类型的限定是不是没有其作用? 不信的话, 继续看:
- public static void main(String[] args) {
- ArrayList<Integer> ints = new ArrayList<Integer>();
- ints.add(1);
- ints.add(2);
- ints.add(3);
- ArrayList<String> sts = new ArrayList<String>();
- sts.add("a");
- sts.add("b");
- sts.add("c");
- System.out.println(ints.getClass() == sts.getClass());
- }
结果是什么呢? 运行来看, 结果为 true
原来是类型擦除惹的祸.
类型擦除
当编译器对带有泛型的 Java 代码进行编译时, 它会去执行类型检查和类型推断, 然后生成普通的不带泛型的字节码, 这种字节码可以被一般的 Java 虚拟机接收并执行, 这种技术被称为擦除(erasure).
因为种种原因, Java 不能实现真正的泛型, 只能使用类型擦除来实现伪泛型, 这样虽然不会有类型膨胀问题, 但是也引起来许多新问题, 所以, SUN 对这些问题做出了种种限制, 避免我们发生各种错误.
编译器可以在对源程序 (带有泛型的 Java 代码) 进行编译时使用泛型类型信息保证类型安全, 对大量如果没有泛型就不会去验证的类型安全约束进行验证, 同时在生成的字节码当中, 将这些类型信息清除掉.
Java 中的泛型与 C++ 模板的比较
GJ(Generic Java)程序的语法在表面上与 C++ 中的模板非常类似, 但是二者之间有着本质的区别.
首先, Java 语言中的泛型不能接受基本类型作为类型参数――它只能接受引用类型. 这意味着可以定义 List<Integer>, 但是不可以定义 List<int>.
其次, 在 C++ 模板中, 编译器使用提供的类型参数来扩充模板, 因此, 为 List<A> 生成的 C++ 代码不同于为 List<B> 生成的代码, List<A> 和 List<B> 实际上是两个不同的类. 而 Java 中的泛型则以不同的方式实现, 编译器仅仅对这些类型参数进行擦除和替换. 类型 ArrayList<Integer> 和 ArrayList<String> 的对象共享相同的类, 并且只存在一个 ArrayList 类.
参考资料
[1] https://baike.baidu.com/item/互换身体/510590?fr=aladdin
[2] https://www.cnblogs.com/wuqinglong/p/9456193.html
[3] https://www.ibm.com/developerworks/cn/java/j-lo-gj/?mhsrc=ibmsearch_a&mhq=类型擦除
来源: https://www.cnblogs.com/davidwang456/p/11585692.html