我们继续上一节课的学习下面将进行获取Field
constructor
Method
详解
获取Field
上节课讲了关于Field
有几个常用的方法大家还记得吗?不记得没关系自己去前面找。这可不是我懒因为自己在寻找过程中记东西会更有效一点点,这也是为啥我分开写没有全部写在一篇的道理。
我们首先说Field [ ] getField()
方法
该方法只能获取public
的成员变量至于能不能获取处public
以外类型的变量你可以试试,路都是自己走出来的嘛。来看下面例子:
//person类里面定义的变量
private int age;
private String name;
public String sex;
package reflect;
import java.lang.reflect.Field;
import java_practice.Person;
public class ReflectDemol {
public static void main(String[] args) throws ClassNotFoundException {
Class cs=Person.class;
Field[] fileds=cs.getFields();
for(Field f: fileds) {
System.out.println(f);
}
}
}
结果:
public java.lang.String java_practice.Person.sex
Field [ ] getField(String name)
方法
可以看出该方法和上一个方法就只是差了个参数,作用就简洁明了了。上一个是获取所有的public
类型的成员变量这个当然是获取某一个了。当然我们获取变量的目的大家应该很清楚无非得到数据和传输数据下面我们实际操作一下。
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Person p=new Person();
Field field2=cs.getField("sex");
Object value2=field2.get(p);//获取sex变量的值
System.out.println(value2);//这个时候sex只是一个空值
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~");
field2.set(p, "男");//设置sex的值
Object value3=field2.get(p);
System.out.println(value3);
}
}
这里给一个小技巧在你遇到一个方法时不知道怎么该方法怎么用最简单最直观的方法就是Ctrl+鼠标左键点解该方法直接看源码。
Field [ ] getDeclareFields()
方法
这个方法跟上面比较多了一个Declare
多个东西就像是加了buff
它就可以获取所有变量了不在考虑是什么修饰符。无论是private
还是protected
——都拿来吧你。下面看操作:
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Person p=new Person();
Field[] fields=cs.getDeclaredFields();
for(Field f: fields) {
System.out.println(f);
}
}
}
结果:
private int java_practice.Person.age
private java.lang.String java_practice.Person.name
public java.lang.String java_practice.Person.sex
Field [ ] getDeclareFields(String name)
方法
具体操作和上面的getField
类似可以用它来得到和修改数据:
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Person p=new Person();
Field name=cs.getDeclaredField("name");
name.setAccessible(true);//暴力反射
Object value=name.get(p);
System.out.println(value);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
name.set(p, "肥学");
Object value2=name.get(p);
System.out.println(value2);
}
}
特别注意这里不同的是在获取private
修饰的变量时要加一句setAccessible(true)
这个是关于忽略访问权限修饰符的安全检查。也称暴力反射。所以学到这里大家要知道在Java里面没有什么绝对的私有。
Constructor获取
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
方法
为了让大家充分的调动,我这里就写这一个例子其他的大家自己写写,不会的在私聊我。
获取constructor
肯定要现有构造方法了呀这里我随便建了两个接着上面的Person.java
:
public Person(int age) {
this.age=age;
}
private Person(String name) {
this.name=name;
}
例:
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Constructor con=cs.getDeclaredConstructor(int.class);
System.out.println(con);
Constructor con2=cs.getDeclaredConstructor(String.class);
System.out.println(con2);
}
}
结果:
public java_practice.Person(int)
private java_practice.Person(java.lang.String)
我们使用constructor
当然要创建对象啊,构造方法不创建对象那不是白瞎了。
下面我又在person
类里面重写了toString
方法
public String toString() {
return name+ " "+ sex + " "+ age;
}
创建对象后
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Constructor con=cs.getDeclaredConstructor(int.class);
System.out.println(con);
Constructor con2=cs.getDeclaredConstructor(String.class);
con2.setAccessible(true);
Object person=con2.newInstance("肥学");//创建对象
System.out.println(person.toString());
}
}
结果:
public java_practice.Person(int)
肥学 null 0
这里新学了newInstance()
它和创建对象的new还是有很多不同的但都是创建对象。好了constructor
获取就介绍到这里
Method获取
Method getMethod(String name, Class<?>... parameterTypes)
方法
下面我们先在person类里面创建两个方法:
public void sleep() {
System.out.println("我睡觉了");
}
public void sleep(String place) {
System.out.println("我睡觉了在"+place);
}
还记的这是方法的重写还是重载吗?评论区告诉我一下。嘻嘻嘻答对了有奖励哦
下面我们就有参和无参进行演示:
public class ReflectDemol {
public static void main(String[] args) throws Exception {
Class cs=Person.class;
Person p=new Person();
Method sleep1=cs.getMethod("sleep");
//执行
sleep1.invoke(p);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Method sleep2=cs.getMethod("sleep",String.class);
//执行
sleep2.invoke(p,"床上");
}
}
结果:
我睡觉了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我睡觉了在床上
这里用到了函数invoke()
由例子我们就可以看出当有参时需要对invoke()
函数里的args
进行参数传递。当然这里也可以用Method[] getDeclaredMethods()
来无视修饰符进行操作但是别忘了setAccessible(true)
,我就不一 一操作了。
这篇我们就学到这里,大家有空也可以去看看python的有趣编程:链接