java反射使用_java反射的用法

反射(运行时的类信息),在java里面得到了大量的使用,尤其是在一些框架里面(注解等等),多多少少都会用到反射,了解java的反射,对我们以后学习框架和写框架都会起到非常的重要!

Class类与java.lang.reflect类库一起对反射的概念进行了支持,该类库包括了FieId、Method以及Constructor类。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样你就可以使用Constructor创建新的对象,用get()和set()方法读取和修改与FieId对象关联的字段,用invoke()方法调用与Method对象关联的方法,另外还可以调用getFieIds()、getMethods()和getConstructors()等很便利的方法,以返回表示字段、方法以及构造器的对象的数组。

首先,我们创建一个类,代码如下

public classReflexObject {private inta;protected intb;intc;public intd;publicReflexObject(){super();

}public ReflexObject(int a, int b, int c, intd) {super();this.a =a;this.b =b;this.c =c;this.d =d;

}private void setA(inta){this.a=a;

System.out.println("我是公有方法");

}protected void setB(intb){this.b=b;

System.out.println("我是私有方法");

}void setC(intc){this.c=c;

System.out.println("我是包方法");

}public void setD(intd){this.d=d;

System.out.println("我是受保护方法");

}

@OverridepublicString toString() {return "ReflexObject [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";

}

}

1⃣️通过getConstructors()、getMethods()和getFields()方法获取类里面的信息,代码如下

public static voidmain(String[] args) {

Constructor>[] constructors = ReflexObject.class.getConstructors();//获取类里面的构造器方法

Method[] methods = ReflexObject.class.getMethods();//获取类里面的方法

Field[] fields = ReflexObject.class.getFields();//获取类里面的属性

for(Constructor>c:constructors){

System.out.println(c.toString());

}

System.out.println("-------------------------------");for(Method m:methods){

System.out.println(m.toString());

}

System.out.println("-------------------------------");for(Field f:fields){

System.out.println(f.toString());

}

System.out.println("-------------------------------");

}

输出结果

3564bd058f0523486344d456f10ba678.png

可以看到,通过getConstructors()、getMethods()和getFields()方法获取类里面的信息只能是公有的,并且可以获取到父类Object的公有方法。

2⃣️用invoke()方法调用与Method对象关联的方法,代码如下

public static voidmain(String[] args) {

ReflexObject rObj=newReflexObject();

System.out.println(rObj);try{

Method methodA= ReflexObject.class.getDeclaredMethod("setA", int.class);

Method methodB= ReflexObject.class.getDeclaredMethod("setB", int.class);

Method methodC= ReflexObject.class.getDeclaredMethod("setC", int.class);

Method methodD= ReflexObject.class.getDeclaredMethod("setD", int.class);

methodA.setAccessible(true);

methodA.invoke(rObj,3);

methodB.setAccessible(true);

methodB.invoke(rObj,3);

methodC.setAccessible(true);

methodC.invoke(rObj,3);

methodD.setAccessible(true);

methodD.invoke(rObj,3);

}catch(Exception e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(rObj);

}

因为invoke(obj,args...)是Method方法,并不知道是要那个对象obj执行改方法,必须指定需要修改那个对象obj,传递的参数args

输出结果如下

2e30cce689c6306d12026bb11835f8cd.png

可以看到,的确是把将属性0都改成了3,执行了方法,甚至是private方法。注意,除了public方法外,其它的都要将setAccessible设置为true,这个大家可以试一下。

3⃣️通过FieId类直接修改属性值

public static voidmain(String[] args) {

ReflexObject rObj=newReflexObject();

System.out.println(rObj);try{

Field fieldA= ReflexObject.class.getDeclaredField("a");

Field fieldB= ReflexObject.class.getDeclaredField("b");

Field fieldC= ReflexObject.class.getDeclaredField("c");

Field fieldD= ReflexObject.class.getDeclaredField("d");

fieldA.setAccessible(true);

fieldA.set(rObj,3);

fieldB.setAccessible(true);

fieldB.set(rObj,3);

fieldC.setAccessible(true);

fieldC.set(rObj,3);

fieldD.setAccessible(true);

fieldD.set(rObj,3);

}catch(NoSuchFieldException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(rObj);

}

输出结果

1c15beaa24ff9d80c9bf6883a061c10f.png

结论和注意点类似2⃣️

4⃣️通过Constructor反射出一个对象,代码如下

public static voidmain(String[] args) {try{

Constructor constructor1 = ReflexObject.class.getDeclaredConstructor();//无参数构造器

Constructor constructor2 = ReflexObject.class.getDeclaredConstructor(int.class,int.class,int.class,int.class);//带参数的构造器

ReflexObject object1 =constructor1.newInstance();

ReflexObject object2= constructor2.newInstance(3,3,3,3);

System.out.println(object1);

System.out.println(object2);

}catch(Exception e) {

e.printStackTrace();

}

}

输出结果如下

1c15beaa24ff9d80c9bf6883a061c10f.png

这里我并没有将setAccessible设置为true,因为我的构造方法都是public,大家可以试一下其它的访问权限。

ok,反射我就写到这里,如果写的有什么问题,大家可以在下面留言,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值