什么是反射?
生物学:反射是机体对内在或外在刺激有规律的反映。
java反射:官方解释是程序在运行状态中,对于任意一个类,都可以知道这个类所有属性和方法,对于任意一个对象都能够调用他的任意方法和属性。
具体方法介绍
首先定一个实体类
package com.leo.demo.reflecttest;
/**
* @ClassName: UserInfo
* @Description: 反射的测试实例
* @Author: leo825
* @Date: 2020-03-03 09:19
* @Version: 1.0
*/
public class UserInfo {
//用户id
private String id;
//用户姓名
private String name;
//用户性别
private String gender;
//用户年龄
private String age;
//测试属性1
public String desc;
//测试属性2
protected String desc2;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "UserInfo{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age='" + age + '\'' +
'}';
}
public String toJsonString() {
return "UserInfo{" +
"\"id\":\"" + id + '\"' +
", \"name\":\"" + name + '\"' +
", \"gender\":\"" + gender + '\"' +
", \"age\":\"" + age + '\"' +
'}';
}
//这是个私有方法
private void privateMethodTest(){
System.out.println("我是是个私有方法");
}
}
上面的实体类非常简单,那我们就测试一下通过反射获取属性和方法
测试定义一个UserInfo对象,并赋值相关属性
UserInfo userInfo = new UserInfo();
userInfo.setId("1");
userInfo.setName("zhangsan");
userInfo.setGender("男");
userInfo.setAge("30");
System.out.println(userInfo.toString());
System.out.println(userInfo.toJsonString());
//获取当前对象的Class
Class clz = userInfo.getClass();
getFields方法
getFields方法是获取当前对象所有的public属性
System.out.println("获取当前对象的属性(public)");
Field[] fields1 = clz.getFields();
for (Field field : fields1) {
System.out.println(field);
}
测试结果
getFields获取当前对象的属性(public)
public java.lang.String com.leo.demo.reflecttest.UserInfo.desc
getDeclaredFields方法
getDeclaredFields获取当前对象的所有属性(public、protected、private)
System.out.println("获取当前对象的属性(public、protected、private)");
Field[] fields2 = clz.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
测试结果
getDeclaredFields获取当前对象的属性(public、protected、private)
private java.lang.String com.leo.demo.reflecttest.UserInfo.id
private java.lang.String com.leo.demo.reflecttest.UserInfo.name
private java.lang.String com.leo.demo.reflecttest.UserInfo.gender
private java.lang.String com.leo.demo.reflecttest.UserInfo.age
public java.lang.String com.leo.demo.reflecttest.UserInfo.desc
protected java.lang.String com.leo.demo.reflecttest.UserInfo.desc2
getMethods方法
getMethods获取当前对象的所有公有方法(不包含私有方法,包含从父类继承的方法)
测试代码:
System.out.println("getMethods获取当前对象的所有公有方法(不包含私有方法,包含从父类继承的方法)");
Method[] methods = clz.getMethods();
for (Method method1 : methods) {
System.out.println(method1);
}
测试结果
getMethods获取当前对象的所有公有方法(不包含私有方法,包含从父类继承的方法)
public java.lang.String com.leo.demo.reflecttest.UserInfo.toString()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getName()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getId()
public void com.leo.demo.reflecttest.UserInfo.setName(java.lang.String)
public void com.leo.demo.reflecttest.UserInfo.setGender(java.lang.String)
public void com.leo.demo.reflecttest.UserInfo.setAge(java.lang.String)
public java.lang.String com.leo.demo.reflecttest.UserInfo.toJsonString()
public void com.leo.demo.reflecttest.UserInfo.setId(java.lang.String)
public java.lang.String com.leo.demo.reflecttest.UserInfo.getGender()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getAge()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods方法
getDeclaredMethods获取当前对象的所有方法(包含私有方法,不包含父类的方法)
System.out.println("getDeclaredMethods获取当前对象的所有方法(包含私有方法,不包含父类的方法)");
Method[] methods2 = clz.getDeclaredMethods();
for (Method method2 : methods2) {
System.out.println(method2);
}
测试结果
getDeclaredMethods获取当前对象的所有方法(包含私有方法,不包含父类的方法)
public java.lang.String com.leo.demo.reflecttest.UserInfo.toString()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getName()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getId()
public void com.leo.demo.reflecttest.UserInfo.setName(java.lang.String)
private void com.leo.demo.reflecttest.UserInfo.privateMethodTest()
public void com.leo.demo.reflecttest.UserInfo.setGender(java.lang.String)
public void com.leo.demo.reflecttest.UserInfo.setAge(java.lang.String)
public java.lang.String com.leo.demo.reflecttest.UserInfo.toJsonString()
public void com.leo.demo.reflecttest.UserInfo.setId(java.lang.String)
public java.lang.String com.leo.demo.reflecttest.UserInfo.getGender()
public java.lang.String com.leo.demo.reflecttest.UserInfo.getAge()
invoke方法
通过反射方式执行对象里面的方法:
System.out.println("invoke通过反射来执行方法(重要)");
Method invokMethod = clz.getDeclaredMethod("privateMethodTest", null);
//私有方法执行需要setAccessible=true
invokMethod.setAccessible(true);
invokMethod.invoke(userInfo, null);
执行私有方法需加要setAccessible=true
,如果不加的话会报如下错:
Exception in thread "main" java.lang.IllegalAccessException: Class com.leo.demo.reflecttest.ReflectTest can not access a member of class com.leo.demo.reflecttest.UserInfo with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:490)
at com.leo.demo.reflecttest.ReflectTest.main(ReflectTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
测试结果
invoke通过反射来执行方法(重要)
我是是个私有方法