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();
}

输出结果

image-20210927102055611

可以看出,反射调用方法确实性能会变慢,但是setAccessible(true);之后,取消检查可以加快速度。

Ps: 此篇博文内容参考于遇见狂神说。供读者阅读参考,感谢~!

posted @ 2021-09-27 10:28  江之南  阅读(82)  评论(0)    收藏  举报