反射----Java高级开发必须懂的

反射----Java高级开发必须懂的

定义:

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

1.在面向对象的世界里,万事万物皆对象。

java语言中,静态的成员、普通数据类型是不是对象呢?不是

类是谁的对象呢?
类是对象,类是java.lang,Class类的实例对象。

好比,自定义一个student对象,student是Student类的实例对象。

任何一个类,都是Class的实例对象,这个实例对象有3中表示方式。

类名.class

对象.getClass()

Class.forName("全类名")

类类型:类也是一个对象,这个对象,我们叫它为类类型。

注意:一个类只可能是class类的一个实例对象。

可以通过类的类类型创建该类的实例对象。

Class s=Student.class;//这个s就是类类型
Student s1=(Student)s.newInstance();


通过new创建对象,都是静态加载类,在编译时刻就需要加载所有的可能使用到的类。

通过Class.forName();是动态加载类,在运行时刻加载

反射的作用:

反射提高程序的灵活性和扩展性,低耦合。常用于系统架构和框架搭建。
代码演示:
1.反射获取方法、成员变量、构造函数的信息

 1 import java.lang.reflect.Constructor;
 2 import java.lang.reflect.Field;
 3 import java.lang.reflect.Method;
 4 
 5 public class Demo3 {
 6     
 7     /**
 8      * 反射获取方法信息
 9      * @author Administrator
10      *
11      */
12     public static void printClassMessage(Object obj){
13         //首先获取类的信息  首先要获取类类型
14         Class c=obj.getClass();  //c就是Object这个类的类类型
15         //获取类的名称
16         System.out.println("类的名称:"+c.getName());
17         //获取所有public的函数,包括父类继承而来的
18         Method[] methods = c.getMethods();
19         //获取所有该类自己声明的方法,不问访问权限
20         Method[] ms = c.getDeclaredMethods();
21         for (int i = 0; i < ms.length; i++) {
22             //获取方法的返回值类型
23             Class<?> returnType = ms[i].getReturnType();
24             //返回值类型的类类型
25             System.out.print(returnType.getName()+" ");
26             //得到方法的名称
27             System.out.print(ms[i].getName()+"(");
28             //获取参数列表的类型的类类型
29             Class<?>[] parameterTypes = ms[i].getParameterTypes();
30             for (Class<?> class1 : parameterTypes) {
31                 System.out.print(class1.getName()+",");
32             }
33             System.out.println(")");
34             
35             printFieldMessage(c);
36         }
37         
38     }
39     /**
40      * 反射获取成员变量信息
41      * @author Administrator
42      *
43      */
44     public  static void printFieldMessage(Object obj) {
45         Class c=obj.getClass();
46         /*
47          * 成员变量也是对象
48          * Filed类封装了关于成员变量的操作
49          */
50         //获取所有public的成员变量的信息
51         Field[] fs = c.getFields();
52         //获取所有自己声明的成员变量的信息,公有、私有都有
53         Field[] fields = c.getDeclaredFields();
54         for (Field field : fields) {
55             //得到成员变量的类型的类类型
56             Class<?> fieldType = field.getType();
57             String typeName = fieldType.getName();
58             System.out.println();
59             //得到成员变量的名称
60             String fieldName = field.getName();
61             System.out.println(typeName+" "+fieldName);
62         }
63     }
64     
65     /**
66      * 打印对象的构造函数的信息
67      */
68     public static void printConsMessage(Object obj){
69         Class c=obj.getClass();
70         /**
71          * 构造函数也是对象
72          * java.lang.Constructor中封装了构造函数的信息
73          */
74         //获取所有Public的构造函数
75         Constructor[] constructors = c.getConstructors();
76         //获取所有自己声明的构造函数
77         Constructor[] cs = c.getDeclaredConstructors();
78         for (Constructor constructor : cs) {
79             System.out.print(constructor.getName()+"(");
80             //获取构造函数的参数列表的类类型
81             Class[] parameterTypes = constructor.getParameterTypes();
82             for (Class class1 : parameterTypes) {
83                 System.out.print(class1.getName()+",");
84             }
85             System.out.println(")");
86         }
87         
88     }
89     public static void main(String[] args) {
90 //        String s="hello";
91 //        Demo3.printClassMessage(s);
92 //        Demo3.printClassMessage(new String());
93 //        Demo3.printFieldMessage(new Integer(1));
94         Demo3.printConsMessage(new Integer(1));
95         
96     }
97 
98 }

2.方法反射的基本操作

 1 import java.lang.reflect.Method;
 2 /**
 3  * 方法反射的基本操作
 4  * @author Administrator
 5  *
 6  */
 7 public class MethodDemo {
 8 
 9     public static void main(String[] args) {
10         //获取一个方法就是获取类的信息,获得类的信息首先就要获得类的类类型
11         A a1=new A();
12         Class c = a1.getClass();
13         //获取Public的方法
14 //        c.getMethod(name, parameterTypes);
15         try {
16 //            c.getMethod("print", new Class[]{int.class,int.class});
17             Method m = c.getMethod("print", int.class,int.class);//同上意思一样,可变参数
18             //方法的反射操作
19             //方法如果没有返回值,返回null,有返回值,就要强制类型转换,返回具体的返回值
20             Object o=m.invoke(a1,new Object[]{10,20});
21             System.out.println("================");
22             Method m1=c.getMethod("print", String.class,String.class);
23             m1.invoke(a1, "Hello","World");
24         } catch (Exception e) {
25             e.printStackTrace();
26         }
27 
28     }
29     
30 }
31 
32 class A{
33     public void print(int a,int b){
34         System.out.println(a+b);
35     }
36     public void print(String a,String b){
37         System.out.println(a.toUpperCase()+","+b.toLowerCase());
38     }
39 }

3.反射与泛型

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 public class Fanxing {
 5 
 6     public static void main(String[] args) {
 7 
 8      List list=new ArrayList();
 9      List<String> list1=new ArrayList<String>();
10      Class<? extends List> class1 = list.getClass();
11      Class<? extends List> class2 = list1.getClass();
12      System.out.println(class1==class2);//true
13 
14     }
15 
16 }
泛型只在编译阶段有效,使用反射技术,可以绕过泛型,达到去泛型化的效果

反射的操作,Class类的操作,Fileld类的操作,方法的操作。都是在编译之后的操作,就是在动态运行时候操作的