Java 反射2
Java 反射2
动态创建对象,并进行后续反射操作。
class user{
private String name;
private int age;
private int id;
//无参构造 快捷键:alt+insert construct 不选
public user() {
}
//有参构造 快捷键:alt+insert construct 全选
public user(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
@Override
public String toString() {
return "user{" +
"name='" + name + ''' +
", age=" + age +
", id=" + id +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
//快捷键:alt+insert Getter 全选
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
}
1、获取类的名字
Class c1 = Class.forName("com.li.reflection.user"); //自己的包
//获得类的名字
System.out.println(c1.getName()); //获得包名和类名
System.out.println(c1.getSimpleName()); //获得类名
2、获得类的属性
//获得类的属性
Field[] fields = c1.getFields();//只能找到public属性
Field[] fields1 = c1.getDeclaredFields(); //可以找到所有属性
for (Field field : fields1) {
System.out.println(field);
}
Field names = c1.getDeclaredField("name"); //找到指定属性的值
System.out.println(names);
3、获得类的方法
Method[] methods = c1.getMethods(); //本类及父类的全部public方法
for (Method method : methods) {
System.out.println("公有的" + method);
}
Method[] methods1 = c1.getDeclaredMethods(); //只能找到本类所有方法
for (Method method : methods1) {
System.out.println("自己的" + method);
}
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
4、获得类的构造器
//获得类的构造器
Constructor[] constructors = c1.getConstructors(); //只能找到本类public构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors(); //只能找到本类所有构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获得指定构造器
Constructor DeclaredConstructor=c1.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println("指定构造器:"+DeclaredConstructor);
4、通过构造器创建对象
//构造一个对象
user user = (user) c1.newInstance(); //本质是调用无参构造
System.out.println(user);
//构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
user use1 =(user)constructor.newInstance("nan",1,20);
System.out.println(use1);
5、通过反射调用方法
//通过反射调用方法
user user2 = (user) c1.newInstance();
//用反射获取具体方法名(前面学过)
Method setName =c1.getDeclaredMethod("setName", String.class);
setName.invoke(user2,"江南"); //invoke 激活 (对象,"值")
System.out.println(user2.getName());
6、通过反射操作属性
//通过反射操作属性
user user3 = (user) c1.newInstance();
//用反射获取具体方法名(前面学过)
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性 需要设置setAccessible 为 ture关闭程序安全检测
name.setAccessible(true); //true 取消语言访问检查 默认为false
name.set(user3,"jiangnan");
System.out.println(user3.getName());
7、测试性能
public static void t1(){
user use = new user();
//开始时间
long starttime=System.currentTimeMillis();
//执行10 亿次
for (int i = 0; i < 1000000000; i++) {
use.getName();
}
//结束时间
long endtime=System.currentTimeMillis();
System.out.println("普通方式执行时间"+(endtime-starttime)+"ms");
}
//反射方式调用
public static void t2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
user use = new user();
Class c1 = use.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
//开始时间
long starttime1=System.currentTimeMillis();
//执行10 亿次
for (int i = 0; i < 1000000000; i++) {
getName.invoke(use,null);//invoke 激活 (对象,"值")
}
//结束时间
long endtime1=System.currentTimeMillis();
System.out.println("反射执行时间"+(endtime1-starttime1)+"ms");
}
//取消检查 反射方式调用
public static void t3() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
user use = new user();
Class c1 = use.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
//开始时间
long starttime2=System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(use,null);//invoke 激活 (对象,"值")
}
long endtime2=System.currentTimeMillis();
System.out.println("取消检查 反射方式执行时间"+(endtime2-starttime2)+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
t1();
t2();
t3();
}
输出结果

可以看出,反射调用方法确实性能会变慢,但是setAccessible(true);之后,取消检查可以加快速度。
Ps: 此篇博文内容参考于遇见狂神说。供读者阅读参考,感谢~!

浙公网安备 33010602011771号