一、反射的概念及在Java中的类反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。在计算机科学领域,反射是一类应用,它们能够自描述和自控制。这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
在Java中的反射机制,被称为Reflection。它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包 括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers等,并可以在执行的过程中,动态生成Instances、变更fields内容或唤起methods。
//
不包含包名前缀的名字
String simpleName = mClass.getSimpleName();
//
类型修饰符
, private, protect, static etc.
int modifiers = mClass.getModifiers();
// Modifier
提供的一些用于判读类型的静态方法
.
Modifier.isPrivate(modifiers);
//
父类的信息
Class superclass = mClass.getSuperclass();
//
构造函数
Constructor[] constructors = mClass.getConstructors();
//
字段类型
Field[] fields = mClass.getFields();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
常用反射方法
下面列举一些反射常见的应用场景,主要从
Student
这个类进行入手。
public class Student {
private final String name;
private int grade = 1;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
private int getGrade() {
return grade;
}
private void goToSchool() {
System.out.println(name + " go to school!");
}
}
1)
反射构建
Student
对象
try {
Class studentClass = Student.class;
//
参数类型为一个
String
的构造函数
Constructor
constructor
=
studentClass.getConstructor(new
Class[]{String.class});
//
实例化
student
对象
Student student = (Student)constructor.newInstance("Li Lei");
System.out.print(student.getName());
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
2)
反射修改私有变量
try {
Student student = new Student("Han MeiMei");
System.out.println("origin grade is " + student.getGrade());
Class studentClass = Student.class;
//
获
取
声
明
的
grade
字
段
,
这
里
要
注
意
getField
和
getDeclaredField
的区别
Field gradeField = studentClass.getDeclaredField("grade");
//
如果是
private
或者
package
权限的,一定要赋予其访问权限
gradeField.setAccessible(true);
//
修改
student
对象中的
Grade
字段值
gradeField.set(student, 2);
System.out.println("after
reflection
grade
is
"
+
student.getGrade());
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
3)
反射调用私有方法
try {
Student student = new Student("Han MeiMei");
//
获取私有方法,同样注意
getMethod
和
getDeclaredMethod
的区别
Method goMethod
= Student.class.getDeclaredMethod("goToSchool",
null);
//
赋予访问权限
goMethod.setAccessible(true);
//
调用
goToSchool
方法。
goMethod.invoke(student, null);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
//
不包含包名前缀的名字
String simpleName = mClass.getSimpleName();
//
类型修饰符
, private, protect, static etc.
int modifiers = mClass.getModifiers();
// Modifier
提供的一些用于判读类型的静态方法
.
Modifier.isPrivate(modifiers);
//
父类的信息
Class superclass = mClass.getSuperclass();
//
构造函数
Constructor[] constructors = mClass.getConstructors();
//
字段类型
Field[] fields = mClass.getFields();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
常用反射方法
下面列举一些反射常见的应用场景,主要从
Student
这个类进行入手。
public class Student {
private final String name;
private int grade = 1;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
private int getGrade() {
return grade;
}
private void goToSchool() {
System.out.println(name + " go to school!");
}
}
1)
反射构建
Student
对象
try {
Class studentClass = Student.class;
//
参数类型为一个
String
的构造函数
Constructor
constructor
=
studentClass.getConstructor(new
Class[]{String.class});
//
实例化
student
对象
Student student = (Student)constructor.newInstance("Li Lei");
System.out.print(student.getName());
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
2)
反射修改私有变量
try {
Student student = new Student("Han MeiMei");
System.out.println("origin grade is " + student.getGrade());
Class studentClass = Student.class;
//
获
取
声
明
的
grade
字
段
,
这
里
要
注
意
getField
和
getDeclaredField
的区别
Field gradeField = studentClass.getDeclaredField("grade");
//
如果是
private
或者
package
权限的,一定要赋予其访问权限
gradeField.setAccessible(true);
//
修改
student
对象中的
Grade
字段值
gradeField.set(student, 2);
System.out.println("after
reflection
grade
is
"
+
student.getGrade());
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
3)
反射调用私有方法
try {
Student student = new Student("Han MeiMei");
//
获取私有方法,同样注意
getMethod
和
getDeclaredMethod
的区别
Method goMethod
= Student.class.getDeclaredMethod("goToSchool",
null);
//
赋予访问权限
goMethod.setAccessible(true);
//
调用
goToSchool
方法。
goMethod.invoke(student, null);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}