Java核心技术知识点笔记—初识反射
前言:反射库(reflection library)是Java组件的体系结构,提供了一个精心设计的丰富的工具集,以便能够编写动态操纵Java代码的程序。反射被大量应用于JavaBeans中,使Java可以支持Visual Basic用户习惯使用的工具,尤其在设计或运行中添加新类时,能够快速应用开发工具动态查询新添加类的能力。
1、反射(reflective):能够分析类能力的程序。它的作用包括:
(1)在运行时分析类的能力
(2)在运行时查看对象,例如,编写一个toString方法供所有类使用
(3)实现通用的数组操作代码
(4)利用Method对象,这个对象很像C++中的函数指针
2、Class类:
2.1、在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。可以通过专门的Java类访问这些信息。保存这些信息的类被称为Class(这个名字容易让人混淆,Object类的getClass()方法会返回一个Class类型的实例)。
2.2、一个Class对象实际上表示的是一个类型,但这个类型不一定是一种类。例如,int不是类,但int.class是一个Class类型的对象。
2.3、常用方法:
(1)getName():返回类的名字。如果类在一个包中,包的名字也会作为类名的一部分。例如:
Random random = new Random();Class<? extends Random> cl = random.getClass();String name = cl.getName();System.out.println(name);
输出:java.util.Random
注意:鉴于历史原因,getName方法应用于数组类型时,会返回一个奇怪的名字。
(2)forName():获取类名对应的Class对象。例如:
String className = "java.util.Random";try {Class<?> aClass = Class.forName(className);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}
注意:className必须是类名或接口名,否则forName()方法将抛出一个checked exception异常。因此上述代码需包裹在try{}catch{}之中,以捕获异常。
(3)T.class代表匹配的类对象。其中T表示任意的Java类型(或void关键字)。例如:
Class<Random> randomClass = Random.class;Class<String[]> stringClass = String[].class;
(4)newInstance():动态创建一个类的实例(此方法已弃用)。例如:
try {Random random1 = random.getClass().newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}
(5)比较:虚拟机为每个类型管理一个Class对象,因此,可以使用"=="运算符进行类对象的比较操作。例如:
Random random = new Random();if (random.getClass()==Random.class){}
3、利用反射分析类的能力
java.lang.reflect包中有三个类:Field、Method和Constructor,分别描述类的域、方法和构造器。三个类都有一个叫做getName的方法,返回项目的名称。另外还有一个getModifiers方法,返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用状况。还可以利用java.lang.reflect包中的Modifier类的静态方法分析getModifiers返回的整型数值。
Class类中的getFields、getMethod、getConstructors方法分别返回类提供的public域、方法和构造器数组,其中包括超类的公有成员。Class类的getDeclaredFields、getDeclaredMethods、getDeclaredConstructors方法分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类的成员。