文章目录
- 2.反射
- 2.1反射的概述
- 2.2 获取 Class类对象的三种方式
- 2.3反射获取构造方法并使用
- 2.3.1Class 类获取构造方法对象的方法
- 2.3.2Constructor类用于创建对象的方法
- 2.3.3小结
- 2.4反射获取成员变量并使用
- 2.4.1Class类获取成员变量对象的方法
- 2.4.2Field类用于给成员变量赋值的方法
- 2.5反射获取成员方法并使用
- 2.5.1Class类获取成员方法对象的方法
- 2.5.2Method类用于执行方法的方法
2.反射
2.1反射的概述
- 反射机制
是在运行状态中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法;这种动态获取信息以及动态调用对象方法的功能称为 Java语言的反射机制。
2.2 获取 Class类对象的三种方式
for
-
三种方式分类
- 类名.class属性
- 对象名.getClass()方法
- Class. forName(全类名)方法
-
代码演示
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.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 study(){
System.out.println("学生在学习");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
/**
* 获取 class 对象的三种方式
*/
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.Class 类中的静态方法forName("全类名")
//全类名:包名 + 类名
Class clazz = Class.forName("com.itheima.myreflect1.Student");
System.out.println(clazz);
//2.通过 class 属性来获取
Class clazz2 = Student.class;
System.out.println(clazz2);
//3.利用对象的 getClass 方法来获取 class 对象
//所有的对象都能获取到类对应的字节码文件,所以说 getClass 方法是定义在Object类中
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz3);
//一个类的Class对象是唯一的
}
}
- 运行结果
2.3反射获取构造方法并使用
2.3.1Class 类获取构造方法对象的方法
- 方法介绍
方法名 | 说明 |
---|---|
Constructor<?>[]getConstructors() | 返回所有公共构造方法对象的数组 |
Constructor<?>[]getDeclaredConstructors() | 返回所有构造方法对象的数组 |
Constructor getConstructor(Class<?> …parameterTypes) | 返回单个公共构造方法对象 |
Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 返回单个构造方法对象 |
- 代码演示
public class Student {
private String name;
private int age;
//私有的有参构造方法
private Student(String name) {
System.out.println("name的值为:"+ name);
System.out.println("private...Student...有参的构造方法");
}
//公共的无参构造方法
public Student(){
System.out.println("public...Student...无参构造方法");
}
//公共的有参构造方法
public Student(String name,int age){
System.out.println("name的值为:"+name+"age的值为:"+age);
System.out.println("public...student...有参构造方法");
}
}
import java.lang.reflect.Constructor;
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// method1();
//method2();
//method3();
//method4();
}
private static void method4() throws ClassNotFoundException, NoSuchMethodException {
//Constructor<T>getDeclaredConstructor(Class<?>...parameterTypes):
//获取单个的构造方法对象(公有或私有都可以获取)
//1.获取Class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor);
}
private static void method3() throws ClassNotFoundException, NoSuchMethodException {
//Constructor<T> getConstructor(Class<?>...parameterTypes):
//返回单个公共构造方法对象
//1.获取Class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
Constructor constructor = clazz.getConstructor(String.class,int.class);//小括号中,一定要跟构造方法的形参保持一致(包括顺序也要一致)
System.out.println(constructor);
}
private static void method2() throws ClassNotFoundException {
// Constructor<?>[] getDeclaredConstructors():
//返回所有构造方法对象的数组
//1.获取Class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
}
private static void method1() throws ClassNotFoundException {
//Constructor<?>[] getConstructors():
//返回所有公共构造方法对象的数组
//1.获取Class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
2.3.2Constructor类用于创建对象的方法
- 方法介绍
方法名 | 说明 |
---|---|
T newInstance(Object … initargs) | 根据指定的构造方法创建对象 |
setAccessible(boolean flag) | 设置为true,表示取消访问检查 |
- 代码演示
/**
* 获取Constructor对象并创建对象
*/
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//T newInstance(Object...initargs):根据指定的构造方法创建对象
// method1();
//1.获取class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
//被 private 修饰的成员,不能直接使用的
//如果用反射强行获取并使用,需要临时取消访问检查
declaredConstructor.setAccessible(true);
Student student2 = (Student) declaredConstructor.newInstance("张三");
System.out.println(student2);
}
private static void method1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//1.获取class对象
Class clazz = Class.forName("com.itheima.myreflect2.Student");
//2.获取构造构造方法对象
Constructor constructor = clazz.getConstructor(String.class, int.class);
//3.利用 newInstance()方法创建 Student 的对象
Student student1 = (Student) constructor.newInstance("张三", 23);
System.out.println(student1);
}
}
2.3.3小结
-
获取 class 对象
三种方式:Class.forName(“全类名”),类名.class,对象名.getClass() -
获取里面的构造方法对象
getConstructor(Class<?> ... parameterTypes) getDeclaredConstructor(Class<?>… parameterTypes) -
如果是 public 的,直接创建对象
newInstance(Object … initargs) -
如果是非 public 的,需要临时取消检查,然后再创建对象
setAccessible(boolean)暴力反射
2.4反射获取成员变量并使用
2.4.1Class类获取成员变量对象的方法
- 方法分类
方法名 | 说明 |
---|---|
Field[] getFields() | 返回所有公共成员变量对象的数组 |
Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |
Field getField(String name) | 返回单个公共成员变量对象 |
Field getDeclaredField(String name) | 返回单个成员变量对象 |
- 代码演示
public class Student {
public String name;
public int age;
public String gender;
private int money = 300;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", money=" + money +
'}';
}
}
import java.lang.reflect.Field;
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
// method1();
//method2();
//method3();
// method4();
}
private static void method4() throws ClassNotFoundException, NoSuchFieldException {
// Field getDeclaredField(String name):返回单个成员变量对象
Class<?> clazz = Class.forName("com.itheima.myreflect3.Student");
Field money = clazz.getDeclaredField("money");
System.out.println(money);
}
private static void method3() throws ClassNotFoundException, NoSuchFieldException {
//Field[] getField(String name):返回单个公共成员变量对象
//想要获取的成员变量必须是真实存在的,且必须是 public 修饰的。
Class clazz = Class.forName("com.itheima.myreflect3.Student");
//获取 name 这个成员变量
Field name = clazz.getField("name");
System.out.println(name);
}
private static void method2() throws ClassNotFoundException {
//Field[] getDeclaredFields():返回所有成员变量对象的数组
Class<?> clazz = Class.forName("com.itheima.myreflect3.Student");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
private static void method1() throws ClassNotFoundException {
//Field[] getFields():返回所有公共成员变量对象的数组
//1.获取Class对象
Class clazz = Class.forName("com.itheima.myreflect3.Student");
//2.获取Field对象
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
}
2.4.2Field类用于给成员变量赋值的方法
- 方法介绍
方法名 | 说明 |
---|---|
void set(Object obj,Object value) | 赋值 |
Object get(Object obj) | 获取值 |
- 代码演示
import java.lang.reflect.Field;
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
// void set(Object obj,Object value):给 obj 对象的成员变量赋值为 value
// Object get( Object obj)返回由 该 field 表示的字段在指定对象上的值。
method1();
method2();
}
private static void method2() throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName("com.itheima.myreflect3.Student");
Field field = clazz.getField("name");
Student student = (Student) clazz.newInstance();
System.out.println( field.get(student));
;
}
private static void method1() throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
//1.获取 class 对象
Class clazz = Class.forName("com.itheima.myreflect3.Student");
//2.获取 name 这个Field对象
Field field = clazz.getField("name");
//3.利用set方法进行赋值。
//3.1先创建一个Student对象
Student student = (Student) clazz.newInstance();
//3.2有了对象才可以给指定的对象进行赋值
field.set(student,"张三");
System.out.println(student);
}
}
2.5反射获取成员方法并使用
2.5.1Class类获取成员方法对象的方法
- 方法分类
方法名 | 说明 |
---|---|
Method[] getMethods() | 返回所有公共成员方法对象的数组,包括继承的 |
Method[] getDeclaredMethods() | 返回所有成员方法对象的数组,不包括继承的 |
Method getMethod(String name, Class<?>…parameterTypes) | 返回单个公共成员方法对象 |
Method getDeclaredMethod(String name, Class<?>…parameterTypes) | 返回单个成员方法对象 |
- 代码演示
public class Student {
//私有的,无参无返回值
private void show(){
System.out.println("私有的show方法,无参无返回值");
}
//公共的,无参无返回值
public void function1(){
System.out.println("function1方法,无参无返回值");
}
//公共的有参无返回值
public void function2(String name){
System.out.println("function2方法,有参无返回值,参数为"+ name);
}
//公共的,无参有返回值
public String function3(){
System.out.println("function3方法,无参有返回值");
return "aaa";
}
//公共的有参有返回值
public String function4(String name){
System.out.println("function4方法,有参有返回值,参数为"+ name);
return "aaa";
}
}
import java.lang.reflect.Method;
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//method1();
//method2();
//method3();
//method4();
}
private static void method4() throws ClassNotFoundException, NoSuchMethodException {
//Method getDeclaredMethod(String name,Class<?>... parameterTypes)
//返回单个成员方法对象
//1.获取 class 对象
Class clazz = Class.forName("com.itheima.myreflect4.Student");
//2.获取成员方法对象
Method method = clazz.getDeclaredMethod("show");
System.out.println(method);
}
private static void method3() throws ClassNotFoundException, NoSuchMethodException {
//Method getMethod(String name,Class<?>...parameterTypes)
//返回单个公共成员方法对象
//1.获取 class 对象
Class clazz = Class.forName("com.itheima.myreflect4.Student");
//2.获取成员方法对象
//获取成员方法function1
Method method1 = clazz.getMethod("function1");
System.out.println(method1);
}
private static void method2() throws ClassNotFoundException {
// Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
//1.获取 class 对象
Class<?> clazz = Class.forName("com.itheima.myreflect4.Student");
//2.获取成员方法对象
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
private static void method1() throws ClassNotFoundException {
// Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
//1.获取 class 对象
Class<?> clazz = Class.forName("com.itheima.myreflect4.Student");
//2.获取成员方法对象
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
2.5.2Method类用于执行方法的方法
- 方法介绍
方法名 | 说明 |
---|---|
Object invoke(Object obj,Object…args) | 运行方法 |
参数一: 用obj对象调用该方法
参数二: 调用方法的传递的参数(如果没有就不写)
返回值: 方法的返回值(如果没有就不写)
- 代码演示
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// Object invoke(Object obj,Object ... args):运行方法
//参数一:用 obj 对象调用该方法
//参数二:调用方法的传递的参数(如果没有就不写)
//返回值:方法的返回值(如果没有就不写)
//1.获取 class 对象
Class clazz = Class.forName("com.itheima.myreflect4.Student");
//2.获取里面的 Method 对象,function4
Method method = clazz.getMethod("function4", String.class);
//3.运行方法
//3.1创建一个 Student对象,来当做方法的调用者
Student student = (Student) clazz.newInstance();
//3.2运行方法
Object result = method.invoke(student, "zhangsan");
//如果方法没有返回值,左边这个接收变量就可以不写了
//4.打印一下返回值
System.out.println(result);
}
}