什么是反射?反射的用法?实例说明。

什么是反射?

生物学:反射是机体对内在或外在刺激有规律的反映。
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获取当前对象的属性(publicpublic 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获取当前对象的属性(publicprotectedprivateprivate 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通过反射来执行方法(重要)
我是是个私有方法
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leo825...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值