java se基础高级之反射

反射的概念

Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
反射机制很重要的一点就是“运行时”,其使得我们可以在程序运行时加载、探索以及使用编译期间完全未知的 .class 文件。
换句话说,Java 程序可以加载一个运行时才得知名称的 .class 文件,然后获悉其完整构造,并生成其对象实体、或对其 fields(变量)设值、或调用其 methods(方法

反射的好处: 通过反射技术可以获取到字节码文件对象,使用这个字节码文件对象就可以获取到一个类的所有信息,包括私有【构造方法对象,成员变量对象,成员方法对象,访问权限修饰符对象...】。
之前的做法:
Student s = new Student();
学习反射之后的做法: 可以不需要显示地出现学生类就能够创建学生类的对象,并且可以动态创建对象,动态赋值,动态调用方法

反射能够获取的相关对象

  • Class 类对象
  • Constructor 构造方法对象
  • Method 成员方法对象
  • Field 成员变量对象
  • Modifier 访问权限修饰符对象
  • Array 数组对象

 创建反射字节码文件对象的三种方式

1.Class clazz = Class.forName("com.ashin.bean.Book");
该方法要注意的是会抛出一个ClassNotFoundException因为输入的字符串代表的类可能不存在。推荐这种方法

2.使用对象的getClass()来反向获取
Book book = new Book();
Class clazz = book.getClass();
必须得先生成对象

3.类字面常量
Class clazz = Book.class;
必须导入该类所在的包

通过反射获取构造方法对象

  • Constructor<?>[] getConstructors() 获取到所有公有修饰的构造方法对象数组
  • Constructor<?>[] getDeclaredConstructors() 获取所有构造方法对象数组,包括私有
  • Constructor<T> getConstructor(Class<?>... parameterTypes) 获取单个公有修饰构造方法对象
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取所有单个修饰的构造方法对象,包括私有

例子

 1 public class ReflectDemo01 {
 2 public static void main(String[] args) throws ClassNotFoundException, FileNotFoundException, IOException {
 3 Student s1 = new Student("张三", 18, "北京西路", 1.80);
 4 Student s2 = new Student("张三", 18, "北京西路", 1.80);
 5 Class<? extends Student> c1 = s1.getClass();
 6 Class<? extends Student> c2 = s2.getClass();
 7 
 8 System.out.println(s1 == s2);
 9 System.out.println(c1 == c2);
10 
11 //    Class<Integer> c3 = int.class;
12 Class<Student> c3 = Student.class;
13 System.out.println(c1 == c3);
14 
15 Properties properties = new Properties();
16 properties.load(new FileReader("config/classinfo.properties"));
17 String classPath = properties.getProperty("className");
18 Class<?> c4 = Class.forName(classPath);
19 System.out.println(c1 == c4);
20 
21 }
22 }

通过反射获取成员变量对象

  • Field[] getFields() 获取所有公有的成员变量对象,包括父类的公有成员
  • Field[] getDeclaredFields() 获取所有本类的成员,包括私有
  • Field getDeclaredField(String name) 获取公有的成员属性,包括父类
  • Field getField(String name) 获取所有本类属性,包括私有
 1 public class ReflectDemo01 {
 2 public static void main(String[] args) throws Exception {
 3 Class<?> c = Class.forName("com.sxt.reflectdemo03.Student");
 4 // 通过字节码文件对象获取成员变量对象
 5 Field[] fields = c.getFields();
 6 for (Field field : fields) {
 7 System.out.println(field);
 8 }
 9 
10 System.out.println("===============");
11 Field[] declaredFields = c.getDeclaredFields();
12 for (Field field : declaredFields) {
13 System.out.println(field);
14 }
15 
16 System.out.println("===============");
17 Field nameField = c.getField("name");
18 System.out.println(nameField);
19 
20 //    Field heightField = c.getField("height");
21 //    System.out.println(heightField);
22 
23 Field heightField = c.getDeclaredField("height");
24 System.out.println(heightField);
25 }
26 }

通过反射获取成员方法对象,并且调用

原来方式:

Student s = new Student();
s.method();

  • Method[] getMethods() 获取所有公有修饰的成员方法对象,包括父类公有方法
  • Method[] getDeclaredMethods() 获取本类所有成员方法对象,包括私有方法
  • Method getMethod(String name, Class<?>... parameterTypes)
  • Method getDeclaredMethod(String name, Class<?>... parameterTypes)
 1 public class ReflectDemo01 {
 2 public static void main(String[] args) throws Exception {
 3 Class<?> c = Class.forName("com.sxt.reflectdemo04.Student");
 4 Object instance = c.getConstructor().newInstance();
 5 
 6 // 通过字节码文件对象获取成员方法对象
 7 Method[] methods = c.getMethods();
 8 for (Method method : methods) {
 9 System.out.println(method);
10 }
11 
12 System.out.println("=================");
13 Method[] declaredMethods = c.getDeclaredMethods();
14 for (Method method : declaredMethods) {
15 System.out.println(method);
16 }
17 
18 System.out.println("==================");
19 // 获取method方法
20 // Method getMethod(String name, Class<?>... parameterTypes)
21 Method method = c.getMethod("method");
22 System.out.println(method);
23 
24 Object invoke = method.invoke(instance);
25 System.out.println(invoke);
26 System.out.println("==================");
27 // 获取setName方法并且赋值
28 Method setNameMethod = c.getMethod("setName", String.class);
29 setNameMethod.invoke(instance, "隔壁老周");
30 
31 // 获取getName方法
32 Method getNameMethod = c.getMethod("getName");
33 Object result = getNameMethod.invoke(instance);
34 System.out.println(result);
35 
36 // 获取add方法并且调用
37 Method addMethod = c.getMethod("add", int.class, int.class);
38 Object result3 = addMethod.invoke(instance, 10, 20);
39 System.out.println(result3);
40 
41 // 获取私有方法并且调用
42 Method showMethod = c.getDeclaredMethod("show");
43 showMethod.setAccessible(true);
44 showMethod.invoke(instance);
45 }
46 }


通过反射获取数组Array对象并且赋值

 1 public class ReflectDemo01 {
 2 public static void main(String[] args) throws Exception {
 3 Class<?> c = Class.forName("com.sxt.reflectdemo05.Demo");
 4 
 5 Object instance = c.getConstructor().newInstance();
 6 
 7 Field arrField = c.getDeclaredField("arr");
 8 
 9 Object arr = arrField.get(instance);
10 
11 //    if (arr instanceof int[]) {
12 //    int[] array = (int[]) arr;
13 //    System.out.println(Arrays.toString(array));
14 //    }
15 //    int i = Array.getInt(arr, 0);
16 //    System.out.println(i);
17 //    Object obj = Array.get(arr, 0);
18 //    System.out.println(obj);
19 //    System.out.println(Array.get(arr, 1));
20 //    System.out.println(Array.get(arr, 2));
21 ////    System.out.println(Array.get(arr, 3));
22 //    int length = Array.getLength(arr);
23 //    System.out.println(length);
24 
25 for (int i = 0; i < Array.getLength(arr); i++) {
26 System.out.println(Array.get(arr, i));
27 }
28 
29 Array.set(arr, 2, 100);
30 System.out.println(Array.get(arr, 2));
31 
32 // 通过反射创建数组
33 Object arrObj = Array.newInstance(String.class, 5);
34 for (int i = 0; i < Array.getLength(arrObj); i++) {
35 System.out.println(Array.get(arrObj, i));
36 }
37 
38 Object arrobj2 = Array.newInstance(int.class, 2, 3);
39 //    Object oneDimensson1 = Array.newInstance(int.class, 1);
40 //    Object oneDimensson2 = Array.newInstance(int.class, 2);
41 //    
42 //    Array.set(arrobj2, 0, oneDimensson1);
43 //    Array.set(arrobj2, 1, oneDimensson2);
44 
45 if (arrobj2 instanceof int[][]) {
46 int[][] array = (int[][]) arrobj2;
47 System.out.println(array);
48 }
49 }
50 }
51 
52 class Demo {
53 
54 int[] arr = new int[3];
55 
56 public Demo() {
57 arr[0] = 10;
58 arr[1] = 20;
59 }

}

原文地址:https://www.cnblogs.com/lqhhome/p/10831875.html