大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
1.什么是java反射
java的反射机制是指在运行状态中,
对于任意一个类,都能知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个属性和方法;
这种动态获取的类的信息,和动态调用对象的方法的功能就是反射机制。
2.反射的作用
在运行时,构造任意一个类的对象
在运行时,判断任意一个类的完整结构,比如属性,方法,内部类,实现接口等
在运行时,判断任意一个对象所属的类
在运行时,调用任意一个对象的属性和方法
在运行时,生成动态代理
3.关键类
Class类是反射类的基础,在java.lang包下,有四种方式可以获取Class类对象
Field,Method,Constructor 都在java.lang.reflect包下
Field是获取Class对象中的属性
Method是获取Class对象中的方法(不包含构造方法)
Construct是获取Class对象中的构造函数
4.测试代码
四种获取Class类的方法:
Person p = new Person();
// 方法一 : 调用运行时类的.class属性
Class c1 = Person.class;
System.out.println("方法一 : 调用运行时类的.class属性: "+c1.toString());
// 方法二 : 通过运行时类的对象,调用getClass()方法
Class c2 = p.getClass();
System.out.println("方法二 : 通过运行时类的对象,调用getClass()方法: "+c2.toString());
// 方法三 : 调用Class的静态方法forName
Class c3 = Class.forName("reflect.Person");
System.out.println("方法三 : 调用Class的静态方法forName: "+c3.toString());
// 方法四 :通过类的加载器
ClassLoader classLoader = Person.class.getClassLoader();
Class c4 = classLoader.loadClass("reflect.Person");
System.out.println("方法四 :通过类的加载器: "+c4.toString());
运行结果是:
方法一 : 调用运行时类的.class属性: class reflect.Person
方法二 : 通过运行时类的对象,调用getClass()方法: class reflect.Person
方法三 : 调用Class的静态方法forName: class reflect.Person
方法四 :通过类的加载器: class reflect.Person
获取Class中的构造函数:
System.out.println("getConstructors为获取类的public的构造方法 ");
Constructor[] constructors1 = c1.getConstructors();
for(int i=0;i<constructors1.length;i++){
System.out.println("constructors ["+i+"] :"+constructors1[i]);
}
Class<? extends Object> c1 = Person.class;
//调用指定的构造器创建运行时类的对象
//我们指定public类型的构造方法Person(String name)来创建对象
Constructor<?> constructor = c1.getDeclaredConstructor(String.class);
Person person = (Person) constructor.newInstance("xl");
System.out.println("调用指定的构造器(public)创建运行时类的对象 --person: "+person);
//我们指定private类型的构造方法Person(String name)来创建对象
constructor = c1.getDeclaredConstructor(String.class,String.class);
constructor.setAccessible(true);
person = (Person) constructor.newInstance("xl2","15");
System.out.println("调用指定的构造器(private)创建运行时类的对象 --person: "+person);
运行结果是:
getConstructors为获取类的public的构造方法
constructors [0] :public reflect.Person(java.lang.String)
constructors [1] :public reflect.Person()
调用指定的构造器(public)创建运行时类的对象 --person: [name : xl ][age : null]
调用指定的构造器(private)创建运行时类的对象 --person: [name : xl2 ][age : 15]
获取Class中全部Method:
Person person = new Person();
Class<? extends Object> c1 = person.getClass();
//getMethods此方法为获取类的public方法,包括父类的public方法
System.out.println("getMethods此方法为获取类的public方法,包括父类的public方法 ");
Method[] method1 = c1.getMethods();
for(int i=0;i<method1.length;i++){
System.out.println("method1 ["+i+"] :"+method1[i]);
}
//getDeclaredMethods此方法为获取类本身声明的所有方法,包括private
System.out.println("getDeclaredMethods此方法为获取类本身声明的所有方法,包括private ");
Method[] method2 = c1.getDeclaredMethods();
for(int i=0;i<method2.length;i++){
System.out.println("method2 ["+i+"] :"+method2[i]);
}
//1.对private类型的方法进行操作
System.out.println("getDeclaredMethod 方法获取类本身声明的方法,包括private类型的方法,以setName(私有)方法为例:");
Method m1 = c1.getDeclaredMethod("setName", String.class);
m1.setAccessible(true);
System.out.println("修改前的person:"+person);
m1.invoke(person, "xl");
System.out.println("修改后的person:"+person);
运行结果是:
getMethods此方法为获取类的public方法,包括父类的public方法
method1 [0] :public java.lang.String reflect.Person.toString()
method1 [1] :public java.lang.String reflect.Person.getName()
method1 [2] :public void reflect.Person.setName(java.lang.String)
method1 [3] :public void reflect.Person.setAge(java.lang.String)
method1 [4] :public java.lang.String reflect.Person.getAge()
method1 [5] :public final void java.lang.Object.wait() throws java.lang.InterruptedException
method1 [6] :public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method1 [7] :public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
method1 [8] :public boolean java.lang.Object.equals(java.lang.Object)
method1 [9] :public native int java.lang.Object.hashCode()
method1 [10] :public final native java.lang.Class java.lang.Object.getClass()
method1 [11] :public final native void java.lang.Object.notify()
method1 [12] :public final native void java.lang.Object.notifyAll()
getDeclaredMethods此方法为获取类本身声明的所有方法,包括private
method2 [0] :public java.lang.String reflect.Person.toString()
method2 [1] :public java.lang.String reflect.Person.getName()
method2 [2] :public void reflect.Person.setName(java.lang.String)
method2 [3] :void reflect.Person.getSex()
method2 [4] :public void reflect.Person.setAge(java.lang.String)
method2 [5] :public java.lang.String reflect.Person.getAge()
getDeclaredMethod 方法获取类本身声明的方法,包括private类型的方法,以setName(私有)方法为例:
修改前的person:[name : null ][age : null]
修改后的person:[name : xl ][age : null]
获取Class类中Field
Class<? extends Object> c1 = Person.class;
System.out.println("getFields此方法为获取类的public属性,包括父类的public属性 ");
Field[] field1 = c1.getFields();
for(int i=0;i<field1.length;i++){
System.out.println("field1 ["+i+"] :"+field1[i]);
}
System.out.println("getDeclaredFields此方法为获取类的本身声明的所有属性,包括private ");
Field[] field2 = c1.getDeclaredFields();
for(int i=0;i<field2.length;i++){
System.out.println("field2 ["+i+"] :"+field2[i]);
}
运行结果是:
getFields此方法为获取类的public属性,包括父类的public属性
field1 [0] :public java.lang.String reflect.Person.age
getDeclaredFields此方法为获取类的本身声明的所有属性,包括private
field2 [0] :private java.lang.String reflect.Person.name
field2 [1] :public java.lang.String reflect.Person.age
对Field进行处理:
Person person = new Person("zj");
Class<? extends Object> c1 = person.getClass();
System.out.println("对public类型的属性进行操作,以类本身的private属性name为例");
Field f1 = c1.getDeclaredField("name");
f1.setAccessible(true);
String name = (String)f1.get(person);
System.out.println("修改前person对象name:"+name);
f1.set(person, "xl");
name = (String)f1.get(person);
System.out.println("修改后person对象的name:"+name);
运行结果是:
对public类型的属性进行操作,以类本身的private属性name为例
修改前person对象name:zj
修改后person对象的name:xl
还有一些对内部类、接口进行的一些操作,这里就不一一列举了。
5.用例:重写Object的toString方法
public class Person {
private String name;
private String age;
public Person(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
StringBuffer result = new StringBuffer();
try {
// 1.获取Class类
Class<? extends Object> clazz = this.getClass();
// 2.获取全部属性
Field [] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
// 3.除去序列化属性
if ("serialVersionUID".equals(fieldName)) {
continue;
}
// 4.拼接方法名
String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1, fieldName.length());
Method method;
Object resultObj;
// 5.通过方法名获取方法
method = clazz.getMethod(methodName);
// 6.get方法没有参数,直接属性对应的值
resultObj = method.invoke(this);
if (resultObj != null && !"".equals(resultObj)) {
result.append("[").append(fieldName).append("]").append(resultObj).append(" ");
}
}
} catch (SecurityException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
return result.toString();
}
}
public class ReflectTest {
public static void main(String[] args){
Person person = new Person("xl","28");
System.out.println(person.toString());
}
}
运行结果是:
[name]xl [age]28
参考:
java核心技术之reflect(一):一个系统学习reflect的Demo(精)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/210131.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...