反射
反射
反射指的是可以在运行时加载,使用编译期间完全未知的类
程序在运行中。可以动态加载一个只有名称的类。对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
一个类只有一个Class对象,在加载一次出来的Class对象也是之前的那一个
加载完类之后,在堆内存里就会产生一个Class对象,类的整个结构信息会放到对应的Class对象中
获取Class对象的三种方式:
1 | public class ReflectionTest { |
获取类的信息
1 |
|
动态操作
1 | public class Demo01 { |
getDeclaredConstructor()这个方法会查找到所有的构造方法,然后通过后面的newInstance()方法来完成实例化,在强转就可以得到类了。如果有参数就输入参数。(注意这个Javabean中最好要有一个无参构造器,不然无参的这个实例化会报错)
反射机制的性能问题
setAccessible(),启用和禁用安全检查的开关,true时取消Java访问检查,但并不是true就能访问,false就不能访问
禁止安全检查可以提高反射的运行速度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42public class Demo02 {
public static void main(String[] args) throws Exception{
test01();
test02();
test03();
}
public static void test01(){
Bean u = new Bean();
long start = System.currentTimeMillis();
for(int i = 0;i<1000000000L;i++){
u.getUname();
}
long end = System.currentTimeMillis();
System.out.println("调用普通方法耗时为:"+(end-start)+"ms");
}
public static void test02() throws Exception{
Bean u = new Bean();
Class clazz = u.getClass();
Method me = clazz.getDeclaredMethod("getUname",null);
long start = System.currentTimeMillis();
for(int i = 0;i<1000000000L;i++){
me.invoke(u, null);
}
long end = System.currentTimeMillis();
System.out.println("运用反射调用方法耗时为:"+(end-start)+"ms");
}
public static void test03() throws Exception{
Bean u = new Bean();
Class clazz = u.getClass();
Method me = clazz.getDeclaredMethod("getUname",null);
me.setAccessible(true);
long start = System.currentTimeMillis();
for(int i = 0;i<1000000000L;i++){
me.invoke(u, null);
}
long end = System.currentTimeMillis();
System.out.println("关闭访问检查后运用反射调用方法耗时为:"+(end-start)+"ms");
}
}这里就可以知道,运用反射调用方法的时间差不多是直接调用方法的时间的10倍,而关闭了访问检查之后就下降到接近5倍的程度
评论