天天看点

java 反射 this_Java高级_反射

1. 反射的基本概念

反射就是通过类的字节码文件来获取类的成员并使用的一项技术

java 反射 this_Java高级_反射

image.png

2. 获取字节码文件对象的三种方式

一个源文件(.java文件)对应一个字节码文件对象(.class文件)

java 反射 this_Java高级_反射

image.png

java 反射 this_Java高级_反射

image.png

java 反射 this_Java高级_反射

image.png

3. 通过反射方式获取构造方法并使用

java 反射 this_Java高级_反射

image.png

首先创建Student类,供之后使用:

package cn.case5;

public class Student {

private String name;

private int age;

public Student() {

}

public Student(String name, int age) {

this.name = name;

this.age = age;

}

// 公有的带参构造

public Student(String name) {

this.name = name;

System.out.println("public name:" + name);

}

// 私有的带参构造

private Student(int age) {

this.age = age;

System.out.println("private age:" + age);

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public void show1() {

System.out.println("我是公共的空参方法");

}

public void show2(int a) {

System.out.println("我是公共的带参方法,你传入的值是" + a);

}

private int show3(int a, int b) {

System.out.println("我是私有的带参方法");

return a + b;

}

@Override

public String toString() {

return "Student{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

package cn.case5;

import java.lang.reflect.Constructor;

public class Test9 {

public static void main(String[] args) throws Exception {

// 1. 获取Student类的字节码对象

Class clazz1 = Class.forName("cn.case5.Student");

// 2. 根据第一步获取的字节码对象,获取指定的构造器对象

// 2.1 获取公共的无参构造

// Constructor con1 = clazz1.getConstructor();

// System.out.println(con1);

// 2.2 获取公共的有参构造

Constructor con2 = clazz1.getConstructor(String.class);

System.out.println(con2);

// // 2.3 获取私有的有参构造

// Constructor con3 = clazz1.getDeclaredConstructor(int.class);

// System.out.println(con3);

//

//

// // 2.4 获取所有的公共构造

// System.out.println("-----------------------------------");

// Constructor[] con4 = clazz1.getConstructors();

// for (Constructor constructor : con4) {

// System.out.println(constructor);

// }

// 获取构造器的名字,看看是哪个类的构造

String name = con2.getName();

System.out.println(name); // cn.case5.Student

// 3. 根据构造器对象创建对应的Student对象

Student stu = (Student)con2.newInstance("张三");

System.out.println(stu);

}

}

4. 通过反射方式获取成员方法并使用

java 反射 this_Java高级_反射

image.png

package cn.case5;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

public class Test11 {

public static void main(String[] args) throws Exception {

// 需求:通过反射的方式获取Student类的成员方法并调用

// 1. 通过反射获取Student类的字节码文件对象

Class clazz1 = Class.forName("cn.case5.Student");

// 2. 通过字节码文件对象获取构造器对象,并实例化

Constructor con1 = clazz1.getConstructor();

Student stu1 = (Student)con1.newInstance();

// 3. 获取该类的成员方法对象,并调用

// 3.1 调用公共的空参方法

Method method1 = clazz1.getMethod("show1");

// 打印方法对象

System.out.println(method1);

// 打印方法名

System.out.println(method1.getName());

// 调用方法

method1.invoke(stu1);

System.out.println("----------------------------------");

// 3.2 调用公共的带参方法

Method method2 = clazz1.getMethod("show2", int.class);

method2.invoke(stu1, 100);

System.out.println("----------------------------------");

// 3.3 调用私有的带参方法

Method method3 = clazz1.getDeclaredMethod("show3", int.class, int.class);

// 开启暴力反射,才能调用私有方法

method3.setAccessible(true);

int sum = (int)method3.invoke(stu1, 100, 200);

System.out.println("您录入的两个数的和是:" + sum);

System.out.println("----------------------------------");

// 3.4 获取所有的成员方法

Method[] method4 = clazz1.getMethods();

for (Method method : method4) {

System.out.println(method);

}

}

}

5. 通过反射方式获取成员变量并使用

java 反射 this_Java高级_反射

image.png

package cn.case5;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

public class Test10 {

public static void main(String[] args) throws Exception {

// 需求:通过反射获取成员变量并使用

// 1. 通过反射获取Student类的字节码文件对象

Class clazz1 = Class.forName("cn.case5.Student");

// 2. 通过字节码文件对象获取构造器对象,并实例化

Constructor con1 = clazz1.getConstructor();

Student stu1 = (Student)con1.newInstance();

// Student stu1 = clazz1.getConstructor().newInstance(); // 链式编程

// 3. 设置学生对象的各个属性值

// 3.1 设置姓名

Field field1 = clazz1.getDeclaredField("name");

// 开启暴力反射,才可以设置私有属性

field1.setAccessible(true);

field1.set(stu1, "张三");

// 3.2 设置年龄

Field field2 = clazz1.getDeclaredField("age");

// 开启暴力反射,才可以设置私有属性

field2.setAccessible(true);

field2.set(stu1, 22);

// 4. 打印对象

System.out.println(stu1); // -->Student{name='张三', age=22}

}

}