java 反射

类加载方法:

所有类的对象都是Class的实例。

类加载时会先加载static静态部分,并且从父类的static到子类static依次加载。

final语句块会作为宏定义被加载到特殊位置。

Person类:

 1 public class Person {
 2     private String name;
 3     private int age;
 4 
 5     public Person() {
 6         // TODO Auto-generated constructor stub
 7     }
 8 
 9     public Person(String name, int age) {
10         this.name = name;
11         this.age = age;
12     }
13 
14     public String getName() {
15         return name;
16     }
17 
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public int getAge() {
23         return age;
24     }
25 
26     public void setAge(int age) {
27         this.age = age;
28     }
29 
30     public void foo(String s) {
31         System.out.println("superman is batman's!!" + "   s");
32     }
33 
34     public void foo(String s, int i) {
35         System.out.println("superman is batman's!!" + "   s" + i);
36     }
37 
38 }

Demo主函数类:

 1 public class ReflectionDemo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         Person person = new Person();
 6         Class demo1=null;
 7         Class demo2=null;
 8         Class demo3=null;
 9         try {
10             // 通过包名加载类
11             demo1 = Class.forName("reflection.Person");
12         } catch (ClassNotFoundException e) {
13             // TODO Auto-generated catch block
14             e.printStackTrace();
15         }
16         // 使用类实例反推类
17         demo2 = person.getClass();
18         // 使用 “类名.class”加载类
19         demo3 = Person.class;
20         System.out.println(demo1.getName());
21         System.out.println(demo2.getName());
22         System.out.println(demo3.getName());
23     }
24 
25 }

输出结果:

reflection.Person
reflection.Person
reflection.Person

使用Class实例化其他类对象:

1 public static void main(String[] args) throws Exception {
2         // 异常未处理
3         Class c = null;
4         c = Class.forName("reflection.Person");
5         Person person = (Person) c.newInstance();
6         person.setName("naruto");
7         System.out.println("Person.name :" + person.getName());
8     }

输出:

Person.name :naruto

这其实是调用Person#Person()默认构造方法,当Person()声明为private私有时,Class.forName()方法会报错。因此在一个类中最好有一个无参构造方法。

通过构造器操作类的有参函数及无参函数:

 1 public static void main(String[] args) {
 2         Class c = null;
 3         Person p1;
 4         Constructor[] cons; // 声明一个构造器数组
 5         try {
 6             // 加载Person类
 7             c = Class.forName("reflection.Person");
 8             // 通过Class实例化其他对象
 9             p1 = (Person) c.newInstance();
10             p1.setName("naruto");
11             System.out.println("p1.name :" + p1.getName());
12             // 获取全部构造函数
13             cons = c.getConstructors();
14             // 构造Person实例,cons数组中的索引值与Person中构造函数声明时的位置有关,如果位置不对应会报错
15             Person p2 = (Person) cons[1].newInstance("tom", 21);
16             System.out.println("p2.name :" + p2.getName() + "p2.age :"
17                     + p2.getAge());
18         } catch (Exception e) {
19             e.printStackTrace();
20         }
21 
22     }

输出:

p1.name :naruto
p2.name :tomp2.age :21

获取类实现的所有接口:

 1 public static void main(String[] args) {
 2         try {
 3             Class<?> c1 = Class.forName("reflection.Person");
 4             Class<?>[] inters = c1.getInterfaces();
 5             for (int i = 0; i < inters.length; i++) {
 6                 System.out.println(inters[i].getName());
 7             }
 8         } catch (Exception e) {
 9             // TODO Auto-generated catch block
10             e.printStackTrace();
11         }
12 
13     }

输出:

reflection.InterfaceDemo

通过反射获取类信息:

 1 public static void main(String[] args) {
 2         try {
 3             Class<?> class1 = Class.forName("reflection.Person");
 4             // 获取Person类的父类
 5             Class<?> class2 = class1.getSuperclass();
 6             // System.out.println("父类:" + class2.getName());
 7             // 获取全部构造方法
 8             Constructor[] cons = class1.getConstructors();
 9             for (Constructor constructor : cons) {
10                 System.out.println("构造方法名:" + constructor.getName());
11                 // 获取构造方法的访问权限
12                 int no = constructor.getModifiers();
13                 System.out.println("访问权限:" + Modifier.toString(no));
14                 // 每个构造方法的参数
15                 Class p[] = constructor.getParameterTypes();
16                 for (int i = 0; i < p.length; i++) {
17                     System.out.print(p[i].getName() + "   ");
18                 }
19                 System.out.println();
20             }
21             // 获取类全部方法信息
22             Method[] methods = class1.getMethods();
23              for (int i = 0; i < methods.length; i++) {
24              // 获取该方法返回值类型
25              Class<?> retuTypes = methods[i].getReturnType();
26              // 获取该方法参数类型
27              Class<?>[] paraTypes = methods[i].getParameterTypes();
28              // 获取该方法抛出的异常
29              Class<?>[] exce = methods[i].getExceptionTypes();
30              System.out.println();
31              }
32             // 获取该类全部非私有的属性信息
33             Field[] fields = class1.getFields();
34             // 获取该类全部属性信息,包括私有属性
35             Field[] fields1 = class1.getDeclaredFields();
36         } catch (Exception e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }
40 
41     }

调用其他类的方法:

 1 public static void main(String[] args) {
 2         try {
 3             Class<?> demo = Class.forName("reflection.Person");
 4             Method method = demo.getMethod("foo",String.class,int.class);
 5             method.invoke(demo.newInstance(),"haha",32);
 6         } catch (Exception e) {
 7             // TODO Auto-generated catch block
 8             e.printStackTrace();
 9         }
10 
11     }
如果方法访问修饰符为private需要修改访问权限
 1 public static void main(String[] args) {
 2         try {
 3             Class<?> demo = Class.forName("reflection.Person");
 4             //getDeclaredMethod()可以访问所有方法,不管方法的访问修饰符是什么
 5             Method method=demo.getDeclaredMethod("fun");
 6             //如果方法访问修饰符为private需要修改访问权限
 7             method.setAccessible(true);
 8             method.invoke(demo.newInstance());
 9         } catch (Exception e) {
10             // TODO Auto-generated catch block
11             e.printStackTrace();
12         }
13 
14     }

访问用private修饰的字段也需要修改访问权限:

 1 public static void main(String[] args) {
 2         try {
 3             Class<?> demo = Class.forName("reflection.Person");
 4             Field field=demo.getDeclaredField("name");
 5             field.setAccessible(true);
 6             Person p=(Person) demo.newInstance();
 7             field.set(p, "pepelu");
 8             System.out.println(field.get(p));
 9         } catch (Exception e) {
10             // TODO Auto-generated catch block
11             e.printStackTrace();
12         }
13     }
原文地址:https://www.cnblogs.com/mada0/p/4721277.html