反射机制:类对象
类对象 | |
概念 |
所有的类,都存在一个类对象。(在一个JVM中,一种类,只会有一个类对象存在。) |
用途 |
提供类本身的信息。 (比如有几种构造方法, 有多少属性,有哪些普通方法。) |
和普通对象的区别 | 打比方,如果类对象是描述数据的结构,普通对象就是描述数据。 |
获取类对象 (三种方式) (均返回Class类型) |
1、Class pClass1=Class.forName(className【包名.类名】); 2、Class PClass2=【类名】.class;//这种方式不会导致静态属性被初始化 3、Class PClass3=new 【类名】().getClass(); 注意:以上三种方式取出来的类对象,都是一样的。 |
类属性 (在静态初始化块中被初始化, 而且只会执行一次) |
1、被static修饰的属性叫类属性,也叫静态属性。 static String copyright; 2、获取类对象时,类属性会被初始化。 static {//静态初始化块
System.out.println("初始化 copyright");
copyright = "版权由Riot Games公司所有";
}
|
创建对象 (指普通对象) |
1、传统方式:通过new 来获取对象。 2、反射机制:先拿到类对象——>获取构造器对象——>在创建对象。(三步走) (1)Class pClass=Class.forName(className【包名.类名】); (2)Constructor c=pClass【类对象】.getConstructor(); (3)【类名】 h=(【类名】) c.newInstance(); *********************************************************** 通过配置文件获取对象。 (1)首先准备一个文本文件hero.config。文本里写着charactor.APHero 或者是charactor.ADHero。 APHero.java
ADHero.java
(2)设计一个方法叫做:public static Hero getHero(); View Code
(3)通过打印h,可以发现,当配置文件里的内容发生变化的时候,就会得到不同的对象。 View Code
源代码不需要发生任何变化,只需要修改配置文件,就可以导致程序的逻辑发生变化, 这是一种基于配置的编程思想。 Spring框架中的IOC和DI的底层就是基于这样的机制实现的。 注意:(3)步骤中得到的普通对象,指向(2)步骤中创建出来的对象。 所以(3)中的对象改变会导致(2)中的对象也同样改变。 |
访问属性 (通过反射机制,修改对象的属性) |
1、 为了访问属性,把name修改为public。 View Code
2、通过反射,修改属性的值。 (1)获取类Hero的名字叫做name的字段 View Code
************************************************************************** getField和getDeclaredField的区别: getField 只能获取public的,包括从父类继承来的字段。 getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))。 |
调用方法 (通过反射机制,调用一个对象的方法) |
1、 为Hero的name属性,增加setter和getter。 View Code
2、通过反射机制,调用Hero的setName。 (1)获取这个名字叫做setName,参数类型是String的方法 Method m=new Hero().getClass()【类对象】.getMethod("setName",String); (2)对h对象,调用这个方法 m.invoke(【普通对象】h,【方法参数】"盖伦"); |
反射机制有什么用 |
1、准备一个配置文件,叫做spring.txt。 【类的名称】class=reflection.Service1 【要调用的方法名】method=doService1 2、首先取出类名称和方法名,然后创建普通对象和要调用的方法对象,最后通过反射去调用这个方法。 public class Test { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) throws Exception { //从spring.txt中获取类名称和方法名称 File springConfigFile = new File("e:\\project\\j2se\\src\\spring.txt"); Properties springConfig= new Properties(); springConfig.load(new FileInputStream(springConfigFile)); String className = (String) springConfig.get("class"); String methodName = (String) springConfig.get("method"); //根据类名称获取类对象 Class clazz = Class.forName(className); //根据方法名称,获取方法对象 Method m = clazz.getMethod(methodName); //获取构造器 Constructor c = clazz.getConstructor(); //根据构造器,实例化出对象 Object service = c.newInstance(); //调用对象的指定方法 m.invoke(service); } } |