关于JAVA反射
反射的定义:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
自己的理解:
java会在编译时将类的信息保存到堆中,反射便是获取的编译时保存的类的信息,反射不是该类的实例,反射更应该理解成类的图 纸。通过这张图纸可以获取反射映射的类的所有信息,也可以通过这张图纸创建一个实例。
//动态调用method
Method method = stuClass.getDeclaredMethod("setName", String.class);
method.invoke(stu1, "Lee");
通过动态调用的方式可以使得程序更为的灵活,如果想要调用私有的方法和属性可以通过setAccessible来关闭安全检测。
反射的效率
package com.lee.myTest;
public class Student {
private int id;
private String name;
private int age;
//默认构造方法一定得有
public Student(){
}
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
package com.lee.myTest;
import java.lang.reflect.Method;
public class TestReflex {
//通过普通调用执行
public static void test01(){
Student student = new Student();
long startTime = System.currentTimeMillis();
for(int i = 0;i < 1000000000;i++)
{
student.getAge();
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms");
}
//通过反射执行
public static void test02(){
try {
//通过反射获取实例
Class<Student> c = (Class<Student>) Class.forName("com.lee.myTest.Student");
Student stu = c.newInstance();
Method m = c.getDeclaredMethod("getId");
long startTime = System.currentTimeMillis();
for(int i = 0; i < 1000000000;i++)
{
m.invoke(stu);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms");
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射执行(关闭安全检查)
public static void test03(){
try {
//通过反射获取实例
Class<Student> c = (Class<Student>) Class.forName("com.lee.myTest.Student");
Student stu = c.newInstance();
Method m = c.getDeclaredMethod("getId");
m.setAccessible(true);//关闭安全检查
long startTime = System.currentTimeMillis();
for(int i = 0; i < 1000000000;i++)
{
m.invoke(stu);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime+"ms");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
test01();
test02();
test03();
}
}
关于输出结果
对于不同的电脑可能会有不同的结果,setAccessible为true可以提高反射的运行效率,并且可以访问到被private修饰的变量。
版权声明: 本文由Lee创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处
本文链接:http://leewant.github.io/2018/07/05/关于JAVA反射/