JAVA 反射机制

java反射机制是在运行状态中,对于任何类都能够得知这个类中的属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性。

JAVA反射机制的功能:

  1. 在运行时判断任意属性类;
  2. 在运行时构造任意一个类方法;
  3. 在运行时判断任意一个类所具有的方法及属性;
  4. 在运行时调动任意一个类方法;
  5. 生成动态代理。

JAVA反射查看类信息:

  1. 使用Class类的forName(String className)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定名;
  2. 调用某个类的class属性来获取该类对应的Class对象;
  3. 调用某个对象的getClass()方法。该方法是java.lang.Object类中的一个方法。
 Class<?> aClass = Class.forName("com.demo.Reflect");
 Class<?> reflectClass= Reflect.class;
 Reflect reflect = new Reflect();
 Class<? extends Reflect> aClass1 = reflect.getClass();

获取Class成员变量

//获取所有属性
Field[] fields = aClass.getDeclaredFields();

//获取 public 属性
Field[] fields = aClass.getFields();
//获取所有指定属性
Field name = aClass.getDeclaredField("name");
//获取public 指定属性
Field brand = aClass.getField("textBack");
brand.set(obj,new String("我需要修改一个测试"));
String te = (String) brand.get(obj);
System.out.println("\n textBack = "+te);

获取Class对象方法

try {
            Class<?> aClass = Class.forName("com.demo.Reflect");
            Object obj = aClass.newInstance();
            //获取所有的方法
            Method[] declaredMethods = aClass.getDeclaredMethods();
           for (Method declaredMethod : declaredMethods) {
                String name = declaredMethod.getName();
                AnnotatedType annotatedReturnType = declaredMethod.getAnnotatedReturnType();
                System.out.println(name + "\n annotatedType = " + annotatedReturnType.getType());
            }

            //获取所有 public 方法
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                String name = method.getName();
                AnnotatedType returnType = method.getAnnotatedReturnType();
                Type type = returnType.getType();
                System.out.println(name + "\n type = " + type);
            }
            Method reflect = aClass.getDeclaredMethod("testReflect", String.class);
            reflect.setAccessible(true);//打开修改私有方法权限
            reflect.invoke(obj, "你好呀");//第一个参数对应调用该方法的实例对象,第二个参数对应该方法的参数
            Method getRef = aClass.getDeclaredMethod("getRef");
            String invoke = (String) getRef.invoke(obj);
            System.out.println(invoke);
            return obj;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
public class Reflect implements Furniture {
    private String ref;
    private String name;
    private double price;
    private String brand;
    private double discounts;
    private String materials;
    private String colors;

    public String getRef() {
        return ref;
    }

    public void setRef(String ref) {
        this.ref = ref;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public double getPrice() {
        return price;
    }

    @Override
    public String getBrand() {
        return brand;
    }

    @Override
    public double getDiscounts() {
        return discounts;
    }

    @Override
    public String getMaterials() {
        return materials;
    }

    @Override
    public String getColor() {
        return colors;
    }

    public String textBack = "我要做测试";

    public void testBack(String test) {
        textBack = test;
    }

    private String annotatedReflect(String ref) {
        return ref;
    }

    private void testReflect(String ref) {
        this.ref= ref;
        System.out.println(ref);
    }
}


代理模式 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问。

代理模式分类:

  1. 动态代理模式;
    运行时生成的。Java编译完成后并没有实际的class文件。而是在运行时动态生成字节码文件,并加载到JVM。
  2. 静态代理模式;
    在编译时就已经实现好。Java编译完成后代理类是一个实际的class文件。

静态代理实现:
RealSubject 对象以及Proxy对象 都实现了 接口Subject。在Proxy对象中,通过构造函数传递目标对象,然后重写接口Subject方法 request(),在该方法中调用RealSubject对象的request()方法。并可以在方法前后添加其他方法。

  RealSubject subject = new RealSubject();
  com.demo.Proxy proxy = new com.demo.Proxy(subject);
  proxy.request();

public class RealSubject implements Subject {
    private static String name = "";
    @Override
    public void request() {
        System.out.println("subject");
    }

    @Override
    public RealSubject reTrue(String str) {
        System.out.println(str);
        this.name = str;
        return this;
    }

    public String getName() {
        return name;
    }
}


public class Proxy implements Subject {
    private Subject subject;

    public Proxy(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void request() {
        System.out.println("proxySubject");
        subject.request();
        System.out.println("proxySubject2");
    }

    @Override
    public Proxy reTrue(String str) {

        return this;
    }
}

代理模式好处: 降低代码耦合度,方便维护。

动态代理:
动态代理主要涉及两个类。一个是 java.lang.reflect.Proxy代理类,另一个是java.lang.reflect.InvocationHandler调用处理器接口,通过重写invoke()方法来执行具体内容。
示例:
第一种方式

   RealSubject subject = new RealSubject();
        //创建一个 InvocationHandler对象
        InvocationHandler proxyHandler = new ProxyHandler(subject);

        Class<?> proxyClass = Proxy.getProxyClass(RealSubject.class.getClassLoader(),
                RealSubject.class.getInterfaces());
        try {
            Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
            Subject realSubject = (Subject) constructor.newInstance(proxyHandler);
            realSubject.request();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

public interface Subject {
    void request();
    Subject reTrue(String str);
}

public class RealSubject implements Subject {
    private static String name = "";
    @Override
    public void request() {
        System.out.println("subject");
    }

    @Override
    public RealSubject reTrue(String str) {
        System.out.println(str);
        this.name = str;
        return this;
    }

    public String getName() {
        return name;
    }
}

public class ProxyHandler implements InvocationHandler {
        private Subject subject;

    public ProxyHandler(Subject subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //定义预处理的工作
        System.out.println("=======before=========");
        Object result =null;
        try {
//            method.invoke(subject,"我的天哪");
            if (method.getName().equals("reTrue")) {
                result = method.invoke(subject, "5555");

            }else{
                result = method.invoke(subject, args);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("=======after=========");
        return result;
    }
}

第二种方式:

 private static void instance() {
 RealSubject subject = new RealSubject();
        //创建一个 InvocationHandler对象
        ProxyHandler proxyHandler = new ProxyHandler(subject);
        //创建一个动态实例 getClassLoader()将生成的字节码加载到JVM中,getInterfaces()实现所有接口,创建Class对象.
        //自定义InvocationHandler
        Subject sbj = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
                RealSubject.class.getInterfaces(), proxyHandler);
        //调用对象方法
        sbj.request();
        RealSubject RealSubject = (RealSubject)sbj.reTrue("ddd");
        System.out.println(RealSubject.getName());
}



public interface Subject {
    void request();
    Subject reTrue(String str);
}

public class RealSubject implements Subject {
    private static String name = "";
    @Override
    public void request() {
        System.out.println("subject");
    }

    @Override
    public RealSubject reTrue(String str) {
        System.out.println(str);
        this.name = str;
        return this;
    }

    public String getName() {
        return name;
    }
}

public class ProxyHandler implements InvocationHandler {
        private Subject subject;

    public ProxyHandler(Subject subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //定义预处理的工作
        System.out.println("=======before=========");
        Object result =null;
        try {
//            method.invoke(subject,"我的天哪");
            if (method.getName().equals("reTrue")) {
                result = method.invoke(subject, "5555");

            }else{
                result = method.invoke(subject, args);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("=======after=========");
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值