Java反射

动态代理

java.lang.reflect.Proxy:提供了为对象产生代理的方法:

复制代码
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
  • loader:指定用哪个类加载器,去加载生成的代理类。
  • interfaces:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法。
  • h:指定生成的代理对象要干什么事。

案例:明星业务被经纪人代理

工程结构

被代理对象的类

java 复制代码
public class BigStar implements IStar{

    private String name;
    public BigStar(){

    }

    public BigStar(String name){
        this.name = name;
    }
    @Override
    public String sing(String name) {
        return name + "正在唱歌";
    }

    @Override
    public String dance() {
        System.out.println(name + "正在跳舞");
        return name + "正在跳舞";
    }
}

代理的接口

java 复制代码
public interface IStar {

    String sing(String name);

    String dance();
}

代理方法

java 复制代码
public class ProxyUtil {
    public static IStar createProxy(BigStar bigStar){

        IStar proxyInstance = (IStar) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),
                new Class[]{IStar.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        if (method.getName().equals("sing")){
                            System.out.println("准备话筒");
                        }else if (method.getName().equals("dance")){
                            System.out.println("准备场地");
                        }
                        return method.invoke(bigStar, args);
                    }
                });
        return proxyInstance;
    }
}

测试

java 复制代码
public class demo {
    public static void main(String[] args) {
        BigStar bigStar = new BigStar("sherry");
        IStar proxy = ProxyUtil.createProxy(bigStar);
        String sing = proxy.sing("小明");
        System.out.println(sing);

        proxy.dance();
    }
}

控制台

获取class对象的方式

  • Class.forName("全类名")
  • 类名.class
  • 对象.getClass

获取构造方法

java 复制代码
利用反射获取构造方法
Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组 
Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>.. parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>.. parameterTypes):返回单个构造方法对象
 
 
Constructor类中用于创建对象的方法
TnewInstance(Object...initargs):根据指定的构造方法创建对象
setAccessible(boolean flag):设置为true,表示取消访问检查

获取成员变量

java 复制代码
利用反射获取成员变量
Class类中用于获取成员变量的方法
Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
 
Field类中用于创建对象的方法
void set(Object obj, Object value):赋值
Object get(Object obj) 获取值。
java 复制代码
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Class<Student> aClass = Student.class;
        //1、获取公有的成员变量
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        //2、获取所有的成员变量
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //3、获取单个成员变量
        Field sex = aClass.getField("sex");
        System.out.println(sex);
        Field name = aClass.getDeclaredField("name");
        System.out.println(name);
        //4、获取权限修饰符
        int modifiers = name.getModifiers();
        //4、获取成员变量名字
        String nameName = name.getName();
        //4、获取成员变量类型
        Class<?> type = name.getType();
        //5、获取成员变量对应的值
        Student student = new Student("女", "sherry", 18);
        name.setAccessible(true);
        Object value = name.get(student);
        System.out.println(value);
        //5、修改对象对应的值
        name.set(student, "张三");
        System.out.println(student);

    }

获取成员方法

java 复制代码
利用反射获取成员方法
 
Class类中用于获取成员方法的方法
Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[]getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes):返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>.. parameterTypes):返回单个成员方法对象
 
Method类中用于创建对象的方法
Object invoke(Object obj, Object... args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
java 复制代码
  Class<Student> aClass = Student.class;

        //1、获取本类中公有的方法(包含父类中的公共方法)
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //2、获取本类中所有的方法(不包含父类中方法)
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        //3、获取指定方法
        Method eat = aClass.getMethod("eat", String.class);
        System.out.println(eat);

        //4、获取指定方法名
        String name = eat.getName();

        //5、获取指定方法的形参
        Parameter[] parameters = eat.getParameters();

        //6、获取指定方法的返回类型
        Class<?> returnType = eat.getReturnType();
        System.out.println(returnType);

        //7、获取指定方法的异常
        Class<?>[] exceptionTypes = eat.getExceptionTypes();
        Student student = new Student();
        eat.invoke(student, "汉堡包");
相关推荐
Theodore_10221 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸2 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象3 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了3 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
----云烟----3 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024063 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·3 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it4 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
懒洋洋大魔王4 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq