Java核心技术第5章(7)
来源:互联网 发布:python web开发 编辑:程序博客网 时间:2024/06/06 08:54
5.7 反射
反射(reflection library)提供了非常丰富的工具集,以便编写能够动态操纵Java代码的程序.这项功能被大量地应用于JavaBeans中,它是Java组件的体系结构.使用反射,Java可以支持Visual Basic用户习惯使用的工具,特别是在设计或运行中添加新类时,能够快速地应用开发工具动态地查询新添加类的能力.能够分析类能力的程序称为反射,反射机制可以用来:
在运行中分析类的能力
在运行中查看对象,例如,编写一个toString类方法供所有类使用
实现通用的数组操纵代码
利用Method对象,这个对象很像C++中的函数指针
5.7.1 Class类
在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每个对象所属的类.虚拟利用运行时类型信息选择相应的方法执行.然而,可以通过专门的Java类访问这些信息,保存这些信息的类称为Class,Object类中的getClass()方法将返回一个Class类型的实例.
Employee e;...Class cl = e.getClass();如同用一个Employee对象表示一个特定的雇员属性一样,一个Class对象将表示一个特定类的属性.最常用的Class方法就是getName,这个方法将返回类的名字,例如:
System.out.println(e.getClass().getName() + " " + e.getName());如果e是一个雇员,则会打印出
Employee Harry如果e是经理,则会打印出
Manager Harry获取Class类对象的第二种方法是调用静态方法forName:
String className = "java.util.Date";Class cl = Class.forName(className);获取Class类对象的第三种方法非常简单,如果T是任意的Java类型,T.class将代表匹配的类对象,例如:
Class cl1 = Date.class;Class cl2 = int.class;Class cl3 = Double[].class;一个Class对象实际上表示的是一个类型.
虚拟机为每个类型管理一个Class对象,因此,可以利用==运算符实现两个类对象比较的操作.例如,
if (e.getClass() == Employee.class) ...还有一个很有用的方法newInstance(),可以用来快速地创建一个类的实例.例如
e.getClass().newInstance();创建了一个与e具有相同类型的实例.newInstance方法调用默认的构造器(没有参数的构造器)初始化新创建的对象.
将forName与newInstance配合起来使用,可以根据存储在字符创中的类名创建一个对象.
String s = "java.util.Date";Object m = Class.forName(s).newInstance();注释:newInstance方法对应C++虚拟构造器的习惯用法.然而,C++的虚拟构造器不是一种语法特性.需要由专门的库支持,Class类与C++中的 type_info类相似,getClass方法与C++中的 typeid 运算符等价.但Java中的Class比C++中的type_info功能强.C++中的type_info只能以字符串的形式显示一个类型的名字,而不能创建那个类型的对象.
5.7.2 捕获异常
当程序运行过程中发生错误时,就会"抛出异常".抛出异常比终止程序要灵活得多,这是因为可以提供一个"捕获"异常的处理器对异常情况进行处理.如果没有提供处理器,程序就会终止,并在控制台上打印出一条信息,其中给出了异常的类型.
异常有两种类型:未检查异常和已检查异常,对于已检查异常,编译器将会检查是否提供了处理器.然而,还有很多常见的异常,例如,访问 null 引用,都属于未检查异常,编译器不会查看是否为这些错误提供了处理器.
Class.forName方法就是一个抛出已检查异常的例子.将可能抛出已检查异常的一个或多个方法调用代码放在 try 块中,然后在 catch 子句中提供处理器代码.
try{ statement that might throw exceptions}catch (Exception e){ handler action}下面是一个示例:
try{ String name = ...; // get Class name Class cl = Class.forName(name); // might throw exception do something with cl}catch (Exception e){ e.printStackTrace();}java.lang.Class方法如下所示:
static Class forName(String className);返回描述类名为className的Class对象
Object newInstance();返回这个类的一个新实例
5.7.3 利用反射分析类的能力
在java.lang.reflect包中有三个类Field,Method,Constructor分别用于描述类的域,方法和构造器.这三个类都有一个叫做getName的方法,用来返回项目的名称.Field类有一个getType方法,用来返回描述域所属类型的Class对象.Method和Constructor类有能够报告参数类型的方法,Method类还有一个可以报告返回返回类型的方法.这三个类还有一个叫做getModifiers的方法,它将返回一个整型数值,用不同的位开关描述 public 和 static 这样的修饰符使用状况.Class类的getFields,getMethods,getConstrution方法将返回类提供的 public 域,方法和构造器数组.
5.7.4 在运行时使用反射分析对象
5.7.5 使用反射编写泛型数组代码
5.7.6 调用任意方法
5.8 继承设计的技巧
下面给出一些对设计继承关系很有帮助的建议.1.将公共操作和域放在超类
2.不要使用受保护的域
3.使用继承实现"is-a"关系
4.除非所有继承的方法都有意义,否则不要使用继承
5.在覆盖方法时,不要改变预期的行为
6.使用多态,而非类型信息
7.不要过多地使用反射
0 0
- Java核心技术第5章(7)
- Java核心技术第5章(5)
- ShapeTest [java核心技术2 第7章]
- Java核心技术第3章(7)
- Java核心技术第4章(7)
- Java核心技术笔记-第7章
- Java核心技术笔记 第5章
- Java核心技术第3章(5)
- Java核心技术第4章(5)
- Java核心技术第5章(1)
- Java核心技术第5章(2)
- Java核心技术第5章(3)
- Java核心技术第5章(4)
- Java核心技术第5章(6)
- Java核心技术笔记-第5章
- Java核心技术第2章
- java核心技术卷1第5章学习心得
- 《JAVA多线程编程核心技术》第4,5,6,7章学习笔记
- MySQL性能优化之table_cache配置参数浅析
- ViewPager轮播图自动无限循环滑动,手指按住停止滑动
- 019redis3.0集群删除节点
- 准确率和召回率介绍
- RESTClient请求的例子
- Java核心技术第5章(7)
- ubuntu12.04下 android 编译环境的搭建
- 利用BufferedReader 、BufferedWriter 复制文件
- 查看 MySQL 数据库中每个表占用的空间大小
- 专题一 Linux下多线程编程——使用Pthread线程库
- 020Java操作redis集群
- php如何向文件中写入换行
- phpstorm xdebug 调试配置
- 转 rtsp rtp rtcp http