黑马程序员技术交流社区
标题: 编译器问题 [打印本页]
作者: 赵亚威 时间: 2013-4-6 22:04
标题: 编译器问题
本帖最后由 赵亚威 于 2013-4-7 06:55 编辑
强制类型转换和泛型都是给编译器看的嘛 自己感觉是 是这样吗?
作者: 王大伟 时间: 2013-4-6 22:18
泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。
可以在集合框架(Collection framework)中看到泛型的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象。
因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:
- Map m = new HashMap();
- m.put("key", "blarg");
- String s = (String) m.get("key");
复制代码
泛型的好处:
(1)类型安全:泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
(2)消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。
(3)潜在的性能收益。泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。
由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
作者: 刘吉庆 时间: 2013-4-6 22:31
学习了!
作者: 陈丽莉 时间: 2013-4-6 22:36
若还有问题,继续追问; 没有的话,请将帖子分类改成【已解决】~
作者: 王川 时间: 2013-4-7 00:09
强制类型转换,又叫造型。分为基本数据类型和引用数据类型两种情况,这里探讨后者,即引用类型的强制类型转换。
对于引用类型来说,什么是强制类型转换呢?简单地说,就是把父类型转换为子类型。因为子类型比父类型的内涵要丰富,无非就
是属性更多功能更强,所以要把父类型转换为子类型,需要强制,所以叫强制类型转换。那么,是不是只要是父类型的变量就可以
转换为子类型呢?事实上不是,这里是有条件限制的。
首先来看发生在什么情况下。我们用一个类型的构造方法构造出一个对象的时候,对象的类型已经确定了,就是这个类型,但是
java允许我们可以不用这个类型的变量引用它,而使用它的父类类型,这时候情况就是我们用一个功能较弱的类型引用了一个功能
较强的对象。然而有时候我们又希望这个对象完全发挥它的作用,就需要用一个它本身的类型的变量来引用它,因为原来那个父类
的变量是不具备这些功能的,不能使用variablename.function()来使其发挥作用,所以还是用它自己的吧。问题是对象已经在内存
中了,已经构造完了,你即使声明一个它本身类型的变量怎么指向它呢?答案是借助原来那个变量,就是它父类型的那个变量,让
新的变量和原来的那个指向同一个对象。方式就是两者之间划等号。可是引用类型变量的相等需要两者类型相同,问题是不相同,
怎么办?那就是把父类型的变量强制转换成子类型。
举个例子来说,比如原来定义了两个类型,FatherClass和SonClass,然后构造了一个SonClass类型的对象,用一个FatherClass类
型的变量father引用了,就像这样:
FatherClass father = new SonClass();
那么,需要将这个对象的类型还原的时候,就可以用这个表达式。
SonClass son = (SonClass)father;
其实,father仍然是FatherClass类型,只不过临时把它的能力提升了一下,然后这一切都交给了son这个变量。但是经过这样处理
以后,这个对象就真正提升了能力了,在son这个变量的引用之下,从此以后恢复真身,可以自由发挥了。
我们刚才说从父类到子类的强制类型转换并不总是能够成功,那什么时候不能成功呢?
在于这个的对象的真实类型,也就是它是使用什么类的构造方法构造出来的。如果它本身就是父类的类型,那么强制类型转换是不
会成功的。
还是举个例子:
FatherClass f = new FatherClass();
SonClass s = (SonClass)f; //这时候就会报错,运行时报错,编译能通过的
编译器只检查类型之间有无继承关系,有则通过;运行时检查真正类型,是则通过。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |