文章目录
Java反射机制一、反射机制概述二、获取class文件对象的三种方式三、通过反射获取构造方法并使用四、通过反射获取成员变量并使用五、通过反射获取成员方法并使用六、通过反射越过泛型检查七、通过反射运行配置文件内容
Java反射机制
一、反射机制概述
反射概述
:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取类的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
要想解剖一个类
,必须先要获取到该类的字节码文件对应的Class类型的对象
,因为解剖使用的是Class类中的方法。
类的成员:
成员变量 Field
构造方法 Constructor
成员方法 Method
二、获取class文件对象的三种方式
a
:Object类的
getClass()方法
b
:静态属性
class
c:Class类中静态方法
forName()
public class MyTest {
public static void main(String
[] args
) throws ClassNotFoundException
{
Class
<? extends MyTest> aClass
= new MyTest().getClass();
Class
<MyTest> myTestClass
= MyTest
.class;
Class
<?> aClass1
= Class
.forName("mydemo.MyTest");
System
.out
.println(myTestClass
==aClass
&&aClass
==aClass1
);
}
}
三、通过反射获取构造方法并使用
public Constructor
<?>[] getConstructors()
public Constructor
<?>[] getDeclaredConstructors()
public Constructor
<T> getConstructor(Class
<?>... parameterTypes
)
public Constructor
<T> getDeclaredConstructor(Class
<?>... parameterTypes
)
T
newInstance()
public void setAccessible(boolean flag
)
import java
.lang
.reflect
.Constructor
;
public class MyTest {
public static void main(String
[] args
) throws Exception
{
Class
<?> aClass
= Class
.forName("mydemo1.Student");
Constructor
<?>[] constructors
= aClass
.getConstructors();
Constructor
<?>[] declaredConstructors
= aClass
.getDeclaredConstructors();
Constructor
<?> constructor
= aClass
.getDeclaredConstructor();
constructor
.setAccessible(true);
Student student
= (Student
) constructor
.newInstance();
System
.out
.println(student
);
System
.out
.println("--------------------------------");
Constructor
<?> constructor1
= aClass
.getConstructor(String
.class, int.class);
Student student1
= (Student
) constructor1
.newInstance("张三", 23);
System
.out
.println(student1
);
}
}
class Student {
private Student() {
System
.out
.println("私有空参构造执行了");
}
public Student(String name
,int age
) {
System
.out
.println("有参构造执行了,"+name
+"=="+age
);
}
}
运行结果:
私有空参构造执行了
mydemo1
.Student
@4554617c
--------------------------------
有参构造执行了
,张三
==23
mydemo1
.Student
@74a14482
Process finished with exit code
0
四、通过反射获取成员变量并使用
public Field
[] getFields()
public Field
[] getDeclaredFields()
public Field
getField(String name
)
public Field
getDeclaredField(String name
)
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.Field
;
public class MyTest {
public static void main(String
[] args
) throws Exception
{
Class
<?> aClass
= Class
.forName("mydemo2.Student");
Constructor
<?> declaredConstructor
= aClass
.getDeclaredConstructor();
declaredConstructor
.setAccessible(true);
Object stu
= declaredConstructor
.newInstance();
Field name
= aClass
.getField("name");
name
.set(stu
,"张三");
Field age
= aClass
.getDeclaredField("age");
age
.set(stu
,23);
Field x
= aClass
.getDeclaredField("x");
x
.setAccessible(true);
x
.set(stu
,3.323);
System
.out
.println(name
.get(stu
)+"=="+age
.get(stu
)+"=="+x
.get(stu
));
}
}
class Student{
public String name
;
int age
;
private double x
;
private Student(){}
}
五、通过反射获取成员方法并使用
public Method
[] getMethods()
public Method
[] getDeclaredMethods()
public Method
getMethod(String name
,Class
<?>... parameterTypes
)
public Method
getDeclaredMethod(String name
,Class
<?>... parameterTypes
)
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.Method
;
public class MyTest {
public static void main(String
[] args
)throws Exception
{
Class
<?> aClass
= Class
.forName("mydemo3.MyClass");
Constructor
<?> declaredConstructor
= aClass
.getDeclaredConstructor();
declaredConstructor
.setAccessible(true);
Object o
= declaredConstructor
.newInstance();
Method show
= aClass
.getMethod("show");
show
.invoke(o
);
Method show1
= aClass
.getDeclaredMethod("show", int.class);
show1
.setAccessible(true);
Object invoke
= show1
.invoke(o
, 22);
System
.out
.println(invoke
);
Method haha
= aClass
.getDeclaredMethod("test", String
.class, int.class);
haha
.setAccessible(true);
Object invoke1
= haha
.invoke(o
, "我是", 777);
System
.out
.println(invoke1
);
}
}
class MyClass{
private MyClass() {
System
.out
.println("私有构造方法执行了");
}
public void show(){
System
.out
.println("无参公共的show方法执行了");
}
private String
show(int num
){
System
.out
.println("有参私有的show方法执行了");
return "show:"+num
;
}
private String
test(String str
,int num
){
System
.out
.println("有参私有的test方法执行了");
return "test:"+str
+num
;
}
}
运行结果:
私有构造方法执行了
无参公共的show方法执行了
有参私有的show方法执行了
show:
22
有参私有的test方法执行了
test
:我是
777
Process finished with exit code
0
六、通过反射越过泛型检查
import java
.lang
.reflect
.Method
;
import java
.util
.ArrayList
;
public class MyTest {
public static void main(String
[] args
) throws Exception
{
ArrayList
<Integer> list
= new ArrayList<>();
list
.add(100);
Class
<? extends ArrayList> aClass
= list
.getClass();
Method add
= aClass
.getDeclaredMethod("add", Object
.class);
add
.setAccessible(true);
add
.invoke(list
,"abc");
System
.out
.println(list
);
}
}
七、通过反射运行配置文件内容
import java
.io
.FileReader
;
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.Method
;
import java
.util
.Properties
;
public class MyTest1 {
public static void main(String
[] args
) throws Exception
{
Properties properties
= new Properties();
properties
.load(new FileReader("configurationFile.properties"));
Class
<?> aClass
= Class
.forName((String
) properties
.get("className"));
Constructor
<?> declaredConstructor
= aClass
.getDeclaredConstructor();
declaredConstructor
.setAccessible(true);
Object o
= declaredConstructor
.newInstance();
Method mathod
= aClass
.getDeclaredMethod((String
) properties
.get("mathodName"));
mathod
.setAccessible(true);
mathod
.invoke(o
);
}
}
class Dog {
private Dog() {
}
public void eat() {
System
.out
.println("狗吃骨头");
}
public void sleep() {
System
.out
.println("狗晚上睡觉");
}
}
class Cat {
private Cat() {
}
public void eat() {
System
.out
.println("猫吃鱼");
}
public void sleep() {
System
.out
.println("猫白天睡觉");
}
}
配置文件内容:
className
=mydemo4
.Dog
mathodName
=sleep
对应运行结果:
狗晚上睡觉
配置文件内容:
className
=mydemo4
.Cat
mathodName
=eat
对应运行结果:
猫吃鱼