java反射学习笔记

1、java反射概念

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

  JAVA反射机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

2、Class类

  Class类用于表示一个.class文件,通过这个类的Class对象可以反射出该类的字段、方法、构造函数、注释等等。任何数据类型都有自己的Class对象。

  获得Class对象的方式有三种:

 1 package reflect;
 2 
 3 public class Dog {
 4     
 5     public static void main(String[] args) throws Exception {
 6         //1、
 7         Class clazz1 = Class.forName("reflect.Dog");
 8         System.out.println(clazz1.getName());
 9         
10         //2、
11         Class clazz2 = Dog.class;
12         System.out.println(clazz2.getName());
13         
14         //3、
15         Class clazz3 = new Dog().getClass();
16         System.out.println(clazz3.getName());
17     }
18     
19 }

运行结果:

reflect.Dog
reflect.Dog
reflect.Dog

3、Constructor类

  Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。Constructor 类的实例对象代表一个类的构造方法。

  3.1、得到某个类所有的构造方法,例:

    Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

  3.2、得到某一个构造方法,例: 

    Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

  3.3、利用构造方法创建实例对象:
    String str = (String)constructor.newInstance(“abc”);

  3.4、Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
    String obj =(String)Class.forName("java.lang.String").newInstance();

  

 1 package reflect;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 public class Dog {
 8     private int id;
 9     private String name;
10     private List list;
11     
12     private Dog(List list) {
13         this.list = list;
14         System.out.println("反射私有构造函数");
15     }
16 
17     public Dog() {
18         System.out.println("dog");
19     }
20     
21     public Dog(String name) {
22         this.name = name;
23     }
24     
25     public Dog(String name, int id) {
26         this.name = name;
27         this.id = id;
28     }
29     
30     public int getId() {
31         return id;
32     }
33 
34     public void setId(int id) {
35         this.id = id;
36     }
37 
38     public String getName() {
39         return name;
40     }
41 
42     public void setName(String name) {
43         this.name = name;
44     }
45 
46     public static void main(String[] args) throws Exception {
47 
48         Class clazz = Class.forName("reflect.Dog");
49         //得到某个类所有的构造方法
50         Constructor[] Constructors  = clazz.getConstructors();
51         
52         //反射无参构造方法
53         Constructor c1 = clazz.getConstructor(null);
54         Dog d = (Dog) c1.newInstance(null);
55         
56         //反射Dog(String name)构造函数
57         Constructor c2 = clazz.getConstructor(String.class);
58         Dog d2 = (Dog) c2.newInstance("guoguo");
59         System.out.println("d2:"+d2.getName());
60         
61         //反射public Dog(String name, int id)构造函数
62         Constructor c3 = clazz.getConstructor(String.class, int.class);
63         Dog d3 = (Dog) c3.newInstance("guoguo",12);
64         System.out.println("d3:"+d3.getId()+"--"+d3.getName());
65         
66         //反射private Dog(List list)构造函数
67         Constructor c4 = clazz.getDeclaredConstructor(List.class);
68         c4.setAccessible(true);  
69         Dog d4 = (Dog) c4.newInstance(new ArrayList());
70         
71         //或者通过class.newIntance获取对象
72         Dog d5 = (Dog) clazz.newInstance();
73     }
74 }

运行结果:

dog
d2:guoguo
d3:12--guoguo
反射私有构造函数
dog

3、Field类

   Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。 

  

 1 package reflect;
 2 
 3 import java.lang.reflect.Field;
 4 import java.util.List;
 5 
 6 public class Dog {
 7     private int id;
 8     private String name;
 9     private List list;
10     
11     private Dog(List list) {
12         this.list = list;
13         System.out.println("反射私有构造函数");
14     }
15 
16     public Dog() {
17         System.out.println("dog");
18     }
19     
20     public Dog(String name) {
21         this.name = name;
22     }
23     
24     public Dog(String name, int id) {
25         this.name = name;
26         this.id = id;
27     }
28     
29     public int getId() {
30         return id;
31     }
32 
33     public void setId(int id) {
34         this.id = id;
35     }
36 
37     public String getName() {
38         return name;
39     }
40 
41     public void setName(String name) {
42         this.name = name;
43     }
44 
45     public static void main(String[] args) throws Exception {
46 
47         Class clazz = Class.forName("reflect.Dog");
48         
49         //获取所有成员变量
50         Field[] fs = clazz.getDeclaredFields();
51         for (Field f : fs) {
52             System.out.println(f.getName());
53         }
54         
55         //private String name; 给变量赋值
56         Dog d1 = new Dog();
57         Field f1 = clazz.getDeclaredField("name");
58         f1.setAccessible(true);
59         f1.set(d1, "guoguo");
60         System.out.println();
61         System.out.println("d1:"+d1.getName());
62         
63         //获取变量的值
64         Dog d2 = new Dog("guoguo");
65         Field f2 = clazz.getDeclaredField("name");
66         f2.setAccessible(true);
67         System.out.println();
68         System.out.println("d2:"+f2.get(d2));
69     }
70 }

运行结果:

id
name
list
dog

d1:guoguo

d2:guoguo

4、Method类

   Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反射的方法可能是类方法或实例方法(包括抽象方法)。

  得到类中的某一个方法:

    例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);


  调用方法:
    通常方式:System.out.println(str.charAt(1));
    反射方式: System.out.println(charAt.invoke(str, 1));
  如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!

 1 package reflect;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 public class Dog {
 6 
 7     public void run() {
 8         System.out.println("run1...");
 9     }
10     
11     public void run(String str) {
12         System.out.println("run2....");
13     }
14     public void run(String str1, String[] str2, int[] id) {
15         System.out.println("run3....");
16     }
17     
18     private void say() {
19         System.out.println("say..");
20     }
21     
22     private String say(String str) {
23         return str;
24     }
25     
26     public static void eat() {
27         System.out.println("eat...");
28     }
29     
30     public static void main(String[] args) throws Exception {
31         Class clazz = Class.forName("reflect.Dog");
32         Dog d = (Dog) clazz.newInstance();
33 
34         //反射public void run()
35         Method run1 = clazz.getMethod("run",null);
36         run1.invoke(d,null);
37         
38         //反射public void run(String str)
39         Method run2 = clazz.getMethod("run",String.class);
40         run2.invoke(d, "str1");
41         
42         //反射public void run(String str1,String str2)
43         Method run3 = clazz.getMethod("run",String.class,String[].class,int[].class);
44         run3.invoke(d, "str", new String[]{"1","2"},new int[]{1});
45         
46         //反射私有方法private void say()
47         Method say = clazz.getDeclaredMethod("say", null);
48         say.setAccessible(true);
49         say.invoke(d, null);
50         
51         //反射带返回值的方法private String say(String str)
52         Method say2 = clazz.getDeclaredMethod("say", String.class);
53         say2.setAccessible(true);
54         String result = (String) say2.invoke(d, "aaa...");
55         System.out.println(result);
56         
57         //反射静态方法
58         Method eat = clazz.getMethod("eat", null);
59         eat.invoke(null, null);    //null
60         
61     }
62 }

运行结果:

run1...
run2....
run3....
say..
aaa...
eat...

原文地址:https://www.cnblogs.com/ming-zi/p/5956186.html