目录
文章目录
前言
一 . 什么是反射?
二 . 反射的使用
1.获取class对象
3.获取成员变量
4.获取成员方法
总结
前言
大家好,今天给大家介绍一下java中的反射,在学习web和框架的时候反射是不可或缺的,偏底层的内容会大量使用反射,很重要。
Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Java的反射机制主要依赖于以下几个类:
Class类:表示一个类或接口,在运行时可以通过该类获取该类的构造方法、字段、方法等信息。
Constructor类:表示一个构造方法,可以通过该类创建对象。
Field类:表示类的字段,可以通过该类访问和修改字段的值。
Method类:表示类的方法,可以通过该类调用方法。
在Java中,可以通过以下几种方式来获取Class对象:
MyClass obj = new MyClass();
Class extends MyClass> clazz = obj.getClass();
Class clazz = MyClass.class;
Class> clazz = Class.forName("com.example.MyClass");
2.获取构造方法
1.Constructor>[] getConstructors() 获取全部构造器(只能获取public修饰的) 2.Constructor>[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到) 3.ConstructorgetConstructor(class>... parameterTypes) 获取某个构造器(只能获取public修饰的) 4.Constructor getDeclaredConstructor(Class>... parameterTypes) 获取某个构造器(只要存在就能拿到,不管是不是private修饰的)
import java.lang.reflect.Constructor;
public class MyClass {
public MyClass() {
}
public MyClass(int value) {
}
public static void main(String[] args) {
try {
// 获取公共的无参构造方法
Constructor> constructor1 = MyClass.class.getConstructor();
System.out.println(constructor1);
// 获取公共的有参构造方法
Constructor> constructor2 = MyClass.class.getConstructor(int.class);
System.out.println(constructor2);
// 获取所有的构造方法
Constructor>[] constructors = MyClass.class.getDeclaredConstructors();
for (Constructor> constructor : constructors) {
System.out.println(constructor);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
输出结果为:
public com.example.MyClass()
public com.example.MyClass(int)
private com.example.MyClass()
Constructor类中常用的方法:
T newInstance(Object....args) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 public void setAccessible(Boolean flag) 设置为true,表示禁止检查访问控制(暴力反射,临时取消权限校验)
student类:
public class Student {
private String name;
private int age;
public Student() {
}
private 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.lang.reflect.Constructor;
public class ReflectionExample {
public static void main(String[] args) {
try {
// 获取有参构造方法
Constructor constructor = Student.class.getDeclaredConstructor(String.class, int.class);
// 设置为可访问 暴力反射 临时取消访问检测
constructor.setAccessible(true);
// 调用构造方法创建实例
Student student = constructor.newInstance("John", 20);
System.out.println(student);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出
Student{name='John', age=20}
在Java中,Class类提供了多个用于获取成员变量的方法。以下是一些常用的方法:
getField(String name)
:获取指定名称的公共成员变量(包括父类中的公共成员变量)。getDeclaredField(String name)
:获取指定名称的成员变量(不包括父类中的成员变量),无论其访问修饰符是什么。getFields()
:获取所有的公共成员变量(包括父类中的公共成员变量)。getDeclaredFields()
:获取所有的成员变量(不包括父类中的成员变量),无论其访问修饰符是什么。import java.lang.reflect.Field;
public class MyClass {
public static void main(String[] args) {
try {
// 获取指定名称的公共成员变量
Field field1 = Student.class.getField("name");
System.out.println(field1);
// 获取指定名称的成员变量
Field field2 = Student.class.getDeclaredField("age");
System.out.println(field2);
// 获取所有的公共成员变量
Field[] fields1 = Student.class.getFields();
for (Field field : fields1) {
System.out.println(field);
}
// 获取所有的成员变量
Field[] fields2 = Student.class.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
Field类中常用的方法
1.void set(Object obj,Object value) 为obj对象里的成员变量赋值为value
2.Object get(Object obj) 取出obj对象中的值
3.public void setAccessible(Boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectionExample {
public static void main(String[] args) {
try {
// 使用反射调用构造方法创建实例
Constructor constructor = Student.class.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
Student student = constructor.newInstance("John", 20);
System.out.println(student);
// 使用反射获取和修改成员变量的值
Field nameField = Student.class.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(student, "Tom");
Field ageField = Student.class.getDeclaredField("age");
ageField.setAccessible(true);
int age = (int) ageField.get(student);
ageField.set(student, age + 1);
System.out.println(student);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果为:
Student{name='John', age=20}
Student{name='Tom', age=21}
java.lang.Class
类中用于获取成员方法的方法:
public Method getMethod(String name, Class>... parameterTypes)
:根据方法名和参数类型获取指定的公共成员方法(包括继承的方法)。
public Method[] getMethods()
:获取所有的公共成员方法(包括继承的方法)。
public Method getDeclaredMethod(String name, Class>... parameterTypes)
:根据方法名和参数类型获取指定的成员方法(不包括继承的方法)。
public Method[] getDeclaredMethods()
:获取所有的成员方法(不包括继承的方法)。
和上面都一样,不再多说,我们来看看 Method中的方法
public Object invoke(Object obj, Object... args)
:通过反射调用该方法,传入指定对象和参数,并返回方法的返回值。
public Class> getReturnType()
:获取方法的返回类型,返回一个Class
对象。
public String getName()
:获取方法的名称。
public int getModifiers()
:获取方法的修饰符,返回一个代表修饰符的整数。
public Class>[] getParameterTypes()
:获取方法的参数类型,返回一个Class
对象数组。
public void setAccessible(boolean flag)
:设置方法是否可访问。
今天的内容就到这了,大家好好理解。