-
反射:reflect
反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也是用一个个Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的实例对象来表示,他们是Field、Method、Contructor、Package、等。
反射:程序的运行时期,对一个类的字节码文件(class)进行解剖,解剖后,看到字节码文件中定义的内容、成员方法、成员变量、构造方法可以运行这个方法,成员变量。、
简单来说:编译时期不知道运行谁,运行时期也不知道运行谁,运行的类和方法,由用户指定。
反射相关的东西—类
Java是面向对象的语言,class文件也是对象,有一个类,描述这个class文件的,java.lang.Class。
构造方法也是一个对象,Constructor类。
成员方法也是一个对象,Method类。
成员变量也是一个对象,Filed类。
获取到一个类的字节码文件对象
getClass()
类名.class
Class.forName()
获取字节码文件中的构造方法,并运行
getConstructor(参数)获取构造方法。
getConstructors()获取所有public的构造方法,存储数组。
getDeclaredConstructor(参数)获取所有的构造方法,非public。
Constructor类的 newInstance()运行获取到的构造方法。
获取成员方法并运行
getMethods()获取成员方法,存储数组。
getMethod(方法名,参数列表)。
getDeclaredMethod(方法名,参数列表)。
Method类的 invoke(对象,方法的参数)。
实例:
[java] view plaincopyprint?
01.public class Person {
02. public Person(int x) {
03.
04. }
05.
06. public Person(String s) {
07. this.name = s;
08. }
09.
10. private Person() {
11.
12. }
13.
14. public String name;
15. private int age;
16.
17. public void show() {
18. System.out.println(name + ":::show:::" + age);
19. }
20.
21. public void show(int x) {
22. System.out.println(name + ":::show:::" + age + x);
23.
24. }
25.
26. private void method() {
27. System.out.println("private method");
28. }
29.
30. public String toString() {
31. return "Person...toString" + name;
32. }
33.}
获取字节码文件对象:
[java] view plaincopyprint?
01./*
02. * 获取字节码文件对象
03. */
04.public class ReflectDemo1 {
05. public static void main(String[] args) throws Exception {
06. method();
07. }
08.
09. // 获取字节码文件对象
10. private static void method() throws Exception {
11. // 第一种方式,通过对象获取,对象的getClass方法
12. // Person p = new Person();
13. // public final Class<?> getClass() Person.class字节码文件对象
14. // Class c = p.getClass();
15. // System.out.println(c);
16.
17. // 第二种方法,通过Person类直接获取,任意的数据类型,都有一个静态属性class返回字节码文件对象
18. Class c1 = Person.class;
19. // System.out.println(c==c1);//T
20. // System.out.println(c.equals(c1));//T
21.
22. // 第三种方法,使用Class类中的静态方法 forName(String 类名)
23. Class c2 = Class.forName("cn.itcast.reflect.Person");
24. System.out.println(c2);
25. System.out.println(c1 == c2);
26. }
27.
28.}
获得构造方法,运行
[java] view plaincopyprint?
01.import java.lang.reflect.*;
02.
03./*
04. * 获得构造方法,运行
05. */
06.public class ReflectDemo2 {
07. public static void main(String[] args) throws Exception {
08. method();
09. }
10.
11. private static void method() throws Exception {
12. // 获得字节码文件对象
13. Class clazz = Class.forName("cn.itcast.reflect.Person");
14. // public Constructor<?>[] getConstructors() 获取构造方法,存储成数组,构造方法public权限
15. Constructor[] con = clazz.getConstructors();
16. for (Constructor c : con) {
17. System.out.println(c);
18. }
19. // Constructor<T> getConstructor(Class<?>... parameterTypes)
20. // 带有一个String类型参数的构造方法
21. Constructor c = clazz.getConstructor(String.class);
22. // 运行构造方法 public T newInstance(Object... initargs)
23. Object obj = c.newInstance("我是谁");
24. System.out.println(obj);
25.
26. // 获取私有构造方法并运行
27. Constructor con1 = clazz.getDeclaredConstructor();
28. System.out.println("----" + con1);
29. con1.setAccessible(true);// 暴力访问
30. Object obj1 = con1.newInstance();
31. System.out.println(obj1);
32.
33. }
34.
35.}