反射的基本使用-练习

反射的基本使用

参考资料:https://www.liaoxuefeng.com/wiki/1252599548343744/1255945147512512 。

反射的基本概念和使用场景本文不提,写一下简单的练习使用和总结。

一 基本使用

  • 1 类对象获取的三种方式
public class Person {}

//获取对象
1 Person p = new Person();
2 Class c = Person.class;
3 Class c = p.getClass();
4 Class c = Class.forName("package.Person");
  • 2 Class获取类对象信息后可执行操作
1 获取类名、类修饰符、父类、接口 等
2 通过反射的方式获取字段信息,并可以进行set get
3 通过反射的方式获取方法类,根据方法名称获取方法实例并执行
4 通过反射的方式获取构造器类,并将其实例化
5 动态代理实现接口的动态实现,无须具体的实现类

二 代码示例

1 测试主类

package testInvoke;

import org.junit.Test;
import java.lang.reflect.*;

/**
 * @author r
 * @description 测试反射
 * @date 2020/11/26
 */
public class WebRequest {

    /**
     * 反射获取字段信息
     * @throws Exception
     */
    @Test
    public void field1() throws Exception {
        Class ucl = UserServer.class;
        System.out.println("----------0-----------");
        System.out.println(ucl.getName());
        System.out.println(ucl.getSuperclass().getName());
        System.out.println(ucl.getInterfaces().length);
        for(Class i : ucl.getInterfaces()){
            System.out.println(i.getName());//只返回当前类直接实现的接口
        }
        System.out.println("----------1-----------");
        System.out.println("===ucl.getFields()===");
        for (Field field:ucl.getFields()) {
            System.out.println(field.toString());
            System.out.println(field.getName());
            System.out.println(field.getType());
            System.out.println(field.getModifiers());
            System.out.println(Modifier.isPublic(field.getModifiers()));
            System.out.println(Modifier.isAbstract(field.getModifiers()));
        }
        System.out.println("----------2-----------");
        System.out.println(ucl.getField("ttt").toString());
        System.out.println("----------3-----------");
        System.out.println("===ucl.getDeclaredFields()===");
        for (Field field:ucl.getDeclaredFields()) {
            System.out.println(field.toString());
        }
    }

    /**
     * 反射获取public字段信息
     * @throws Exception
     */
    @Test
    public void field2(){
        UserServer u = new UserServer("测试字段!");
        Class ucl = u.getClass();
        Field field = null;
        try {
            field = ucl.getDeclaredField("xxx");
        } catch (NoSuchFieldException e) {
            System.out.println("UserServer类xxx字段 不存在");
        }
        try {
            Object o = field.get((Object) u);
            System.out.println(o.toString()); //测试字段!
        } catch (IllegalAccessException e) {
            System.out.println("字段获取失败,检查字段访问权限");
        }
    }

    /**
     * 反射 获取/设置 private字段信息
     * @throws Exception
     */
    @Test
    public void field3(){
        UserServer u = new UserServer("测试字段xxx","测试字段xxx1");
        Class ucl = u.getClass();
        Field field = null;
        try {
            field = ucl.getDeclaredField("xxx1");
        } catch (NoSuchFieldException e) {
            System.out.println("UserServer类xxx字段 不存在");
        }
        /**
         *获取私有变量需设置此参数
         * 调用Field.setAccessible(true)的意思是,别管这个字段是不是public,一律允许访问。
         */
        field.setAccessible(true);
        try {
            Object o = field.get((Object) u);
            System.out.println(o.toString()); //测试字段xxx1
        } catch (IllegalAccessException e) {
            System.out.println("字段获取失败,检查字段访问权限");
        }

        try {
            field.set(u,"测试字段===");
            System.out.println(u.toString()); //UserServer{xxx='测试字段xxx', xxx1='测试字段==='}
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射实现方法调用,当调用非public方法时,需:Method.setAccessible(true);同上。
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Test
    public void method1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        UserServer u = new UserServer("测试字段xxx","测试字段xxx1");
        Class ucl = u.getClass();
        //非静态方法
        Method m = ucl.getDeclaredMethod("see", String.class, int.class);
        m.invoke(u,"Hello, 世界",100); //Hello, 世界 ; Let me see see! ; 100
        //静态方法
        Method sm = ucl.getDeclaredMethod("see");
        sm.invoke(null); //Let me see see!
    }

    /**
     * 多态
     */
    @Test
    public void method2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        TestUser testUser = new TestUser();
        Class cl = testUser.getClass();
        Method m = cl.getDeclaredMethod("hello");
        m.invoke(new UserServer()); //UserServer{xxx='null', xxx1='null'}
    }

    /**
     * 构造器创建对象
     */
    @Test
    public void constru1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class cl = UserServer.class;
        Constructor cons = cl.getConstructor(String.class);
        UserServer u = (UserServer)cons.newInstance("xxx");
        System.out.println(u.toString());
    }

    /**
     * 动态代理,实现接口的动态实现(无需具体的实现类)
     * interface Use(){}
     */
    @Test
    public void proxyion(){
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(method.getName().equals("find")){
                    System.out.println("接口 Use 的 find 方法 的实现!");
                }
                return null;
            }
        };

        Use use = (Use)Proxy.newProxyInstance(
                Use.class.getClassLoader(),
                new Class[]{Use.class},
                handler
        );

        use.find();
    }

}

2 UserServer.class

package testInvoke;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserServer extends TestUser {
    public String xxx;
    private String xxx1;
    private static final Logger logger = LoggerFactory.getLogger(UserServer.class);

    public UserServer() {
    }

    public UserServer(String xxx) {
        this.xxx = xxx;
    }

    public UserServer(String xxx, String xxx1) {
        this.xxx = xxx;
        this.xxx1 = xxx1;
    }

    @Override
    public String toString() {
        return "UserServer{" +
                "xxx='" + xxx + '\'' +
                ", xxx1='" + xxx1 + '\'' +
                '}';
    }

    @Override
    public void hello() {
        String s = "UserServer{" +
                "xxx='" + xxx + '\'' +
                ", xxx1='" + xxx1 + '\'' +
                '}';
        System.out.println(s);
    }

    public void run (){
        System.out.println("Let me run run!");
    }

    public static void see (){
        System.out.println("Let me see see!");
    }

    public void see (String a1,int a2){
        System.out.println(a1 + " ; Let me see see! ; "+a2);
    }
}

3 TestUser.class

package testInvoke;

/**
 * @author r
 * @description 测试UserServer父类
 * @date 2020/12/3
 */
public class TestUser {
    public Integer ttt;

    public void hello() {
        String s = "TestUser{" +
                "ttt=" + ttt +
                '}';
        System.out.println(s);
    }
}

4 Use.class

package testInvoke;

public interface Use {
    void find();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值