关于反射的一些方法和技巧琢磨半天害怕自己忘了,于是乎写到博客里给我以后看看,源码如下:
package cn.sjy;
import java.util.Arrays;
/**
* @author Shi Jun Yi
* @version 1.0
* @date 2020/11/1 19:33
* 通过反射如何获取方法,构造器,属性等
*/
public class Test5 {
public static void main(String[] args ) throws Exception{
Class c1 = Class.forName("cn.sjy.Person");
//获取类的名字
System.out.println(c1.getName());
//获取类的简化的名字
System.out.println(c1.getSimpleName());
//获取类的属性
System.out.println("===================");
//只能找到public修饰的属性
System.out.println(Arrays.toString(c1.getFields()));
//可以找到private修饰的属性
System.out.println(Arrays.toString(c1.getDeclaredFields()));
//获取指定的属性
System.out.println(c1.getDeclaredField("name"));
//获取类的方法
System.out.println("===================");
//获取所有的public修饰的方法,并且可以把继承的方法也打印出来
System.out.println(Arrays.toString(c1.getMethods()));
//获取所有的方法,仅仅是本类
System.out.println(Arrays.toString(c1.getDeclaredMethods()));
//获取指定的方法
System.out.println(c1.getMethod("getId"));
System.out.println("=======================");
//获得指定的构造器
System.out.println(Arrays.toString(c1.getConstructors()));
System.out.println(c1.getConstructor(int.class,String.class));
}
}
package cn.sjy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author Shi Jun Yi
* @version 1.0
* @date 2020/11/1 19:34
* 动态创建对象,通过反射
*/
public class Test4 {
public static void main(String[] args ) throws Exception{
//获取Class对象
Class c1 = Class.forName("cn.sjy.Person");
//实例化该对象,创建由此类对象表示的新的对象
Person person = (Person) c1.newInstance();
//newInstance()方法规定调用无参的构造函数
System.out.println(person);
//获得一个类的构造器
Person person2 = (Person)c1.getConstructor(int.class, String.class).newInstance(2017021, "虎哥");
//将这个类的构造器进行实例化
System.out.println(person2);
//调用一个普通方法
Method fan = c1.getDeclaredMethod("fan");
//需要忽略访问权限修饰符的安全检查--》暴力反射
fan.setAccessible(true);
fan.invoke(person);
//操作属性
Field id = c1.getDeclaredField("id");
id.setAccessible(true);
id.set(person,123);
System.out.println(id.get(person));
}
}
Person类
package cn.sjy;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private int id;
private String name;
/**普通方法*/
private void fan(){
System.out.println("通过反射来调用普通方法!");
}
}
普通方法,反射(打开检测),反射(关闭检测)三种性能对比分析:
package cn.sjy;
import java.lang.reflect.Field;
/**
* @author Shi Jun Yi
* @version 1.0
* @date 2020/11/1 21:03
*/
public class Test6 {
/**
* 普通方法调用
*/
public static void test01() throws Exception{
Person person = new Person();
//获取系统当前时间
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
person.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法执行10亿次:"+(endTime-startTime)+"ms");
}
/**
* 反射调用 打开检测
*/
public static void test02() throws Exception{
Class<Person> c = Person.class;
Field id = c.getDeclaredField("id");
//获取系统当前时间
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
id.get(c.newInstance());
}
long endTime = System.currentTimeMillis();
System.out.println("运用反射打开检测执行10亿次:"+(endTime-startTime)+"ms");
}
/**
* 反射调用 关闭检测
*/
public static void test03() throws Exception{
Class<Person> c = Person.class;
Field id = c.getDeclaredField("id");
id.setAccessible(true);
//获取系统当前时间
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
id.get(c.newInstance());
}
long endTime = System.currentTimeMillis();
System.out.println("运用反射关闭检测执行10亿次:"+(endTime-startTime)+"ms");
}
public static void main(String[] args ) throws Exception{
test01();;
test02();;
test03();;
}
}
结果如下
由此可得出结论,普通方法的执行效率很高,反射的执行效率较低,当调用反射比较多的时候可以关闭检测以提高效率。
未完,待续~~