java反射
1、反射有什么用
在程序运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。要想获取它的属性、方法,必须要先获取class字节码文件对象
2、反射怎么用
既然反射可以直接操作字节码class文件,那么就需要先获取到它的字节码文件
2.1 获取class文件
需要获取class对象的类
public class Student {
private String id;
private String name;
private String age;
private String gender;
public Student() {
}
public Student(String id, String name, String age, String gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
// get、set、toString略
}
1、Class.forName(对象的全路径)
注意:这种获取class对象的方式会导致类加载,但是仅仅执行类的静态代码块
try {
Class<?> studentClass1 = Class.forName("reflectTest.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、对象.getClass()
Student student = new Student();
Class<? extends Student> studentClass2 = student.getClass();
3、任何类型.class
Class<Student> studentClass3 = Student.class;
2.2 使用字节码文件实例化对象
可以使用:class对象.newInstance() 来实例化一个对象
Student student1 = studentClass3.newInstance()
注意:newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以
3、反编译(反射)一个类的属性
3.1 class
1、 创建对象
class.newInstance()
Student student = studentClass3.newInstance();
2、返回完整类名带包名
class.getName()
String name = studentClass3.getName();
System.out.println(name);
// --------输出结果------
reflectTest.Student
3、返回类名
class.getSimpleName()
String simpleName = studentClass3.getSimpleName();
System.out.println(simpleName);
// --------输出结果------
Student
4、返回类中public修饰的属性
class.getFields()
Field[] fields = studentClass3.getFields();
5、返回类中所有的属性
class.getDeclaredFields()
Field[] declaredFields = studentClass3.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
// --------输出结果------
private java.lang.String reflectTest.Student.id
private java.lang.String reflectTest.Student.name
private java.lang.String reflectTest.Student.age
private java.lang.String reflectTest.Student.gender
6、返回类中指定的属性
class.getDeclaredField(【属性名】)
Field id = studentClass3.getDeclaredField("id");
System.out.println(id);
7、获取属性的修饰符列表
class.getModifiers()
返回的修饰符是一个数字,每个数字是修饰符的代号【一般配合Modifier类的toString(int x)方法使用】
可以作用在类、属性、方法上
// 获取类的修饰符
int modifiers = studentClass3.getModifiers();
System.out.println(modifiers);
// --------输出结果------
1
/// 获取属性的修饰符
int modifiers = studentClass3.getDeclaredField("id").getModifiers();
System.out.println(modifiers);
// --------输出结果------
2
修饰符 | 返回值 |
---|---|
public | 1 |
private | 2 |
protected | 4 |
static | 8 |
final | 16 |
synchronized | 32 |
volatile | 64 |
transient | 128 |
native | 256 |
interface | 512 |
abstract | 1024 |
strict | 2048 |
8、返回类中所有实例方法
class.getDeclaredMethods()
Method[] declaredMethods = studentClass3.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//---------输出结果------------
public java.lang.String reflectTest.Student.toString()
public java.lang.String reflectTest.Student.getName()
public java.lang.String reflectTest.Student.getId()
public void reflectTest.Student.setName(java.lang.String)
public void reflectTest.Student.setId(java.lang.String)
public java.lang.String reflectTest.Student.getAge()
public java.lang.String reflectTest.Student.getGender()
public void reflectTest.Student.setGender(java.lang.String)
public void reflectTest.Student.setAge(java.lang.String)
9、返回类中所有的构造方法(class.getDeclaredConstructors())
Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
//---------输出结果------------
public reflectTest.Student()
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
10、返回调用类的父类(class.getSuperclass())
Class<? super Student> superclass = studentClass3.getSuperclass();
System.out.println(superclass);
//---------输出结果------------
class java.lang.Object
11、返回调用类实现的接口集合(class.getInterfaces())
Class<?>[] interfaces = studentClass3.getInterfaces();
for (Class<?> anInterface : interfaces) {
System.out.println(anInterface);
}
//--------Student没有实现接口,因此没有输出结果-----
3.2 Filed
获取Filed:
class.getDeclaredField(String name)
class.Field[] getDeclaredFields()
1、获取属性名
declaredField.getName()
Field field = studentClass3.getDeclaredField("id");
String name = field.getName();
System.out.println(name);
//---------输出结果------------
id
2、获取修饰符
见3.1中的7
3、返回属性的数据类型
field.getType()
Class<?> type = field.getType();
System.out.println(type);
//---------输出结果------------
class java.lang.String
4、设置属性值
属性.set(对象, 值);
利用反射为已经new出来的对象的指定的字段赋值
Student student = new Student();
// 获取属性的Filed
Field field = studentClass3.getDeclaredField("id"); // 获取student对象的id的filed
field.set(student,"我是id"); // 为对象student的id赋值
System.out.println(student.getId());
//---------输出结果------------
我是id
一般,private修饰的属性被封装起来,是不能够被访问的,在反射中可以打破封装,为private修饰的类进行赋值
Field gender = studentClass3.getDeclaredField("gender");
gender.setAccessible(true); // 默认false,设置为true为打破封装
field.set(student,"男");
// ------如果不使用setAccessible,则会报错
5、读取属性值
属性.get(对象);
// 弄一个供测试使用的对象
Student student = new Student();
student.set("3131");
// 使用反射中的filed对象获取对象中存储的值
Field field = studentClass3.getDeclaredField("id"); // 获取student对象的id的filed
Object o = field.get(student); // 获取student的id的值
System.out.println(o);
//---------输出结果------------
3131
3.3 Method
获取Method
public Method[] getDeclaredMethods()
public Method getDeclaredMethod(String name, Class<?>… parameterTypes)
1、返回方法名
declaredMethod.getName()
Method[] declaredMethods = studentClass3.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
String name = declaredMethod.getName();
System.out.println(name);
}
//---------输出结果------------
toString
getName
getId
setName
setGender
getGender
setId
setAge
getAge
2、获取方法的修饰符
同3.1的第7条
3、获取方法的返回结果类型
method.getReturnType()
Method method = studentClass3.getDeclaredMethod("getAge");
Class<?> returnType = method.getReturnType();
System.out.println(returnType);
//---------输出结果------------
class java.lang.String
4、获取方法的入参类型
me.getParameterTypes()
Method me = studentClass3.getDeclaredMethod("setAge", String.class);
Class<?>[] parameterTypes = me.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println(parameterType);
}
//---------输出结果------------
class java.lang.String
5、调用方法
Method.invoke(对象, 实参);
Student student = new Student();
//使用反射调用对象的方法
Method me = studentClass3.getDeclaredMethod("setAge", String.class);
Object invoke = me.invoke(student, "53");
System.out.println(invoke);
System.out.println(student.getAge());
//---------输出结果------------
null
53
3.4 Constructor
public Constructor<?>[] getDeclaredConstructors()
public Constructor getDeclaredConstructor(Class<?>… parameterTypes)
1、获取构造名
Construct.getName()
Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor.getName());
System.out.println(declaredConstructor);
System.out.println("==========");
}
//---------输出结果------------
reflectTest.Student
public reflectTest.Student()
==========
reflectTest.Student
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
==========
2、获取构造的修饰符
同3.1的7
3、获取构造的形参数据类型列表
public Class<?>[] getParameterTypes()
Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[1];
System.out.println(declaredConstructor);
Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println(parameterType);
}
//---------输出结果------------
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
class java.lang.String
class java.lang.String
class java.lang.String
class java.lang.String
4、创建对象
注意,括号中的参数为可选入参,如果要构建有参构造的对象,那么需要在括号中传入参数
public T newInstance(Object … initargs)
获取空参构造的反射,并创建对象
Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[0];
Object o = declaredConstructor.newInstance();
System.out.println(o);
//---------输出结果------------
Student{id='null', name='null', age='null', gender='null'}
获取有参构造的反射,并创建对象
Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[1];
Object o = declaredConstructor.newInstance("001","张三","32","男");
System.out.println(o);
//---------输出结果------------
Student{id='001', name='张三', age='32', gender='男'}