黑马程序员------反射机制

 

1.1 反射机制
* JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;
* 对于任意一个对象,都能够调用它的任意一个方法和属性;
* 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
*

*反射其实就是动态加载一个指定的类,并获取该类中的所有的内容。

*而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。

*就是把JAVA类中的各种成分反射成为相应的JAVA类
*简单说:反射技术可以理解为对一个类进行解剖。

 

1.2 反射机制原理图:

 


*
*
* 要想要对字节码文件进行解剖,必须要有字节码文件对象.
* 如何获取字节码文件对象呢?(示例1)

 示例1:
1
public class ReflectDemo { 2 public static void main(String[] args) throws ClassNotFoundException { 3 4 getClassObject_1(); 5 6 } 7 /* 8 * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。 9 * 可是用Class类中的方法完成。 10 * 该方法就是forName. 11 * 这种方式只要有名称即可,更为方便,扩展性更强。 12 */ 13 14 public static void getClassObject_1() throws ClassNotFoundException { 15 16 String className = "cn.itcast.bean.Person"; 17 18 Class clazz = Class.forName(className); 19 20 System.out.println(clazz); 21 } 22 23 }

 


1.3 反射的好处:大大的增强了程序的扩展性。


1.4 反射的基本步骤:
1、获得Class对象,就是获取到指定的名称的字节码文件对象。
2、实例化对象,获得类的属性、方法或构造函数。
3、访问属性、调用方法、调用构造函数创建对象。

得到类的字节码文件相同,这三种方式。
1.Class cls1=类名.class 相对简单,还是需要明确类名
2.cls1.getclass();必须要明确具体的类,并创建对象
3.class.forName("完整的类名(带包名)");

 

 示例2:获取Class中的构造函数

 1 package cn.itcast.reflect.demo;
 2 
 3 import java.io.FileReader;
 4 import java.lang.reflect.Constructor;
 5 
 6 public class ReflectDemo2 {
 7 
 8     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, Exception {
 9 
10         createNewObject_2();
11         
12     }
13     
14     public static void createNewObject_2() throws Exception {
15         
16         /*
17          * 当获取指定名称对应类中的所体现的对象时,
18          * 而该对象初始化不使用空参数构造该怎么办呢?
19          * 既然是通过指定的构造 函数进行对象的初始化,
20          * 所以应该先获取到该构造函数。 通过字节码文件对象即可完成。
21          * 该方法是:getConstructor(paramterTypes);
22          * 
23          */
24 
25         String name = "cn.itcast.bean.Person";
26         //找寻该名称类文件,并加载进内存,并产生Class对象。
27         Class clazz = Class.forName(name);
28         //获取到了指定的构造函数对  象。
29         Constructor constructor = clazz.getConstructor(String.class,int.class);
30         
31         //通过该构造器对象的newInstance方法进行对象的初始化。
32         Object obj = constructor.newInstance("小明",38);
33         
34             
35         
36     }
37 
38     public static void createNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
39         
40         
41         //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
42 //        并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.
43 //        cn.itcast.bean.Person p = new cn.itcast.bean.Person();
44         
45         //现在:
46         String name = "cn.itcast.bean.Person";
47         //找寻该名称类文件,并加载进内存,并产生Class对象。
48         Class clazz = Class.forName(name);
49         //如何产生该类的对象呢?
50         Object obj  = clazz.newInstance();
51         
52         
53         
54         
55     }
56 }

 

示例3:获取Class的字段

 1 package cn.itcast.reflect.demo;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 public class ReflectDemo3 {
 6 
 7     public static void main(String[] args) throws Exception {
 8         
 9         getFieldDemo();
10         
11     }
12 
13     /*
14      * 获取字节码文件中的字段。
15      */
16     public static void getFieldDemo() throws Exception {
17         
18         Class clazz = Class.forName("cn.itcast.bean.Person");
19         
20         Field field = null;//clazz.getField("age");//只能获取公有的,
21         
22         field = clazz.getDeclaredField("age");//只获取本类,但包含私有。 
23         
24         //对私有字段的访问取消权限检查。暴力访问。
25         field.setAccessible(true);
26         
27         Object obj = clazz.newInstance();
28         
29                 //为对象的属性赋值        
30                 field.set(obj, 89);
31         
32         //获取某对象的某属性值
33         Object o = field.get(obj);
34         
35         System.out.println(o);
36         
37 //        cn.itcast.bean.Person p = new cn.itcast.bean.Person();
38 //        p.age = 30;
39         
40     }
41     
42 }
43     

 

示例4:获取Class中的方法

 1 package cn.itcast.reflect.demo;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Method;
 5 
 6 public class ReflectDemo4 {
 7 
 8     public ReflectDemo4() {
 9     }
10 
11     public static void main(String[] args) throws Exception {
12 
13         getMethodDemo_3();
14         
15     }
16     
17     
18 
19     public static void getMethodDemo_3() throws Exception {
20         
21         Class clazz = Class.forName("cn.itcast.bean.Person");
22         
23         Method method = clazz.getMethod("paramMethod", String.class,int.class);
24         
25         Object obj = clazz.newInstance();
26         
27         method.invoke(obj, "小强",89);
28         
29         
30     }
31 
32     public static void getMethodDemo_2() throws Exception {
33         
34         Class clazz = Class.forName("cn.itcast.bean.Person");
35         
36         Method method = clazz.getMethod("show", null);//获取空参数一般方法。
37         
38 //        Object obj = clazz.newInstance();
39         Constructor constructor = clazz.getConstructor(String.class,int.class);
40         Object obj = constructor.newInstance("小明",37);
41         
42         
43         method.invoke(obj, null);
44         
45         
46         
47     }
48 
49     /*
50      * 获取指定Class中的所有公共函数。
51      */
52     public static void getMethodDemo() throws Exception {
53         
54         Class clazz = Class.forName("cn.itcast.bean.Person");
55         
56         Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 
57         methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 
58         for(Method method : methods){
59             System.out.println(method);
60         }
61         
62         
63     }
64 
65 }

 

练习:反射练习

代码:

PCI.java

1 package cn.itcast.reflect.test;
2 
3 public interface PCI
4 {
5         public void open();
6         public void close();
7 }

 

SoundCard.java

 1 package cn.itcast.reflect.test;
 2 
 3 public class SoundCard implements PCI
 4 {
 5         public void open(){
 6                 System.out.println("sound open");
 7         }
 8 
 9         public void close(){
10                 System.out.println("sound close");
11         }
12 }

 

NetCard.java

 1 package cn.itcast.reflect.test;
 2 
 3 public class NetCard implements PCI
 4 {
 5         public void open(){
 6                 System.out.println("net open");
 7         }
 8 
 9         public void close(){
10                 System.out.println("net close");
11         }
12 }

 

Mainboard.java

 1 package cn.itcast.reflect.test;
 2 
 3 public class Mainboard
 4 {
 5         public void run(){
 6                 System.out.println("main board run...");
 7         }
 8 
 9         public void usePCI(PCI p){
10                 if(p != null){
11                         p.open();
12                         p.close();
13                 }
14         }
15 }

 

pci.Properties

1 pci1=cn.itcast.reflect.test.SoundCard
2 pci2=cn.itcast.reflect.test.NetCard

 

ReflectTest.java

 1 package cn.itcast.reflect.test;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 
 6 import java.util.Properties;
 7 
 8 /*
 9 * 电脑运行
10 */
11 public class ReflectTest
12 {
13         public static void main(String[] args) throws Exception {
14                 
15                 Mainboard mb = new Mainboard();
16         
17                 mb.run();
18                 //每次添加一个设备都需要修改代码传递一个新创建的对象
19                 //mb.usePCI(new SoundCard());
20                 //能不能不修改代码就可以完成这个动作
21                 //不用new完成,而是只获取其class文件,在内部实现创建对象的动作。
22                 
23                 File configFile = new File("pci.properties");
24 
25                 Properties prop = new Properties();
26                 FileInputStream fis = new FileInputStream(configFile);
27 
28                 prop.load(fis);
29 
30                 for(int x = 0; x < prop.size(); x++){
31 
32                         String pciName = prop.getProperty("pci" + (x + 1));
33 
34                         Class clazz = Class.forName(pciName);//用Class去加载这个pci子类
35 
36                         PCI p = (PCI)clazz.newInstance();
37 
38                         mb.usePCI(p);
39                 }
40 
41                 fis.close();
42         }
43 }

运行结果:

posted on 2015-06-16 20:15  若诺  阅读(184)  评论(0编辑  收藏  举报