转载自 https://www.cnblogs.com/haodawang/p/5967185.html

首先我得先请大家不要误会,博客园说转载的文章放在文章分类里,原创的文章用随笔写,我开先还以为随笔是拿来写抒情文的(滑稽),后来才发现不是这样的,但是自己所有的文章都在文章分类里了,又懒得搬运,所以我就用js重定向了一下。所以现在标题栏里进来的都是文章分类哦,大部分都是自己原创的,转载会注明转载的url。

废话不多说,今天我想来聊一下java里的反射和动态代理的问题,因为这两个东西实在撩人,而且动态代理百度几乎都是千篇一律,今天我写这篇博文希望能帮助大家,顺便也是为了巩固自己,毕竟自己也折腾了好久。

先来看看反射。
java里的class文件加载分为两种情况,一种就是类型是编译器已知的,这种文件的.class文件在编译的时候,编译器会把.class文件打开检查,但是注意不是加载哦,第二种就是我们可能是从别的地方获取到了一个引用,然后动态的把这个未知类型的引用的对象的.class文件加载进jvm虚拟机里。

那么我们称前者为RTTI,即Run- Time Type Identification 运行时类型识别,有的人把RTTI翻译成 Run - Time Type Information ,我个人认为是不对的,因为我觉得它概括的不够全面,所以我建议大家把I 翻译成Identification更容易理解。

我们称后者为“反射”,这对于正在学习JAVA的人来说可是一个新的名词,但反射也是作为一个java的核心技术的存在。下面就来看看反射究竟有多重要吧。

反射

在java里提供了一个叫做reflect的库,这个库里封装了Method,Constructor,field,Proxy,InvocationHandler 等类,这些类的API在我们学习反射会很有帮助。

反射最大的作用就在于我们可以不在编译时知道某个对象的类型,而在运行时得到。同时我们只需要得到我们想得到的类的名字即可(如果不在一个包,必须写完整的名字包括包名)。

package com.bike;import java.lang.reflect.*;public class Main {public static void main(String[] args) throws Exception{//返回A的构造方法Constructor c = A.class.getConstructor();//返回A类的所有为public 声明的构造方法Constructor[] cons = A.class.getConstructors();//返回A类所有的构造方法,包括privateConstructor[] cons2 = A.class.getDeclaredConstructors();//返回A类的第一个public 方法Method m = A.class.getMethod("say");//执行m.invoke(A.class.newInstance(), null);//返回A类所有的public 方法Method[] ms = A.class.getMethods();//返回A类所有的方法,包括privateMethod[] allMs = A.class.getDeclaredMethods();//返回A类的public字段Field field = A.class.getField("i");System.out.println(field.get(A.class.newInstance()));//返回A类的static 字段System.out.println(field.get(null));}
}class A{public int i = 1;public static int b = 2;public A(){System.out.println("无参构造");}private A(String s){System.out.println("有参构造"+s);}public void say(){System.out.println("say");}
}

这里我只是简单的把API罗列了一下,大家可以自己动手试试,我这里就不再去描述了。
通过上面的例子我们可以看出我们只用知道一个类的名字便可以得知它内部方法和字段,那么这里已经强烈的体现到了反射的作用。只是我这里做例子的时候把A作为了自己内部包的一个类,而在实际开发中,你可能是跨包的,所以你必须要写上全名才行。

关于.class类字面常量的知识请参照我的上一篇博文:http://www.cnblogs.com/haodawang/articles/5954368.html

代理

接下来我们来看一下代理。
代理可以帮助我们进行很好的封装,使底层的代码能够有效的隐藏起来。
为了区别,我们先来看看静态代理吧。


public class Main2 {//这里传入的是接口类型的对象,方便向上转型,实现多态public static void consumer(ProxyInterface pi){pi.say();}public static void main(String[] args) {// TODO Auto-generated method stubconsumer(new ProxyObject());}
}//代理接口
interface ProxyInterface{public void say();
}//被代理者
class RealObject implements ProxyInterface{//实现接口方法@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("say");}}//代理者
class ProxyObject implements ProxyInterface{@Overridepublic void say() {// TODO Auto-generated method stub//dosomething for exampleSystem.out.println("hello proxy");new RealObject().say();System.out.println("this is method end");}}
output:
hello proxy
say
this is method end

这就是静态代理,理解这个应该不难。
下面我们再来看看动态代理

import java.lang.reflect.*;public class Main {static void customer(ProxyInterface pi){pi.say();}public static void main(String[] args){RealObject real = new RealObject();ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));customer(proxy);}
}interface ProxyInterface{void say();
}//被代理类
class RealObject implements ProxyInterface{public void say(){System.out.println("i'm talking");}
}//代理类,实现InvocationHandler 接口
class ProxyObject implements InvocationHandler{private Object proxied = null;public ProxyObject(){}public ProxyObject(Object proxied){this.proxied  = proxied;}public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {System.out.println("hello");return arg1.invoke(proxied, arg2);};
}

可以看到动态代理的代理类是实现了一个InvocationHandler的接口,我们通过reflect.Proxy的类的newProxyInstance方法就可以得到这个接口的实例,然后再来作为参数传递进去,这里每一个在代理类上处理的东西也会被重定向到调用处理器上。

至于动态代理和静态代理的区别,即动态代理是动态的创建代理和动态的处理方法的,这也是反射的一个重要体现之处。

Java动态代理与反射详解相关推荐

  1. java动态代理、反射

    Ø java动态代理.反射 .1.1.   反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等,一下是实例: package cn.java.reflect; import java ...

  2. Java动态代理源码详解

    一.概述   前言:本文除了讲解JDK动态代理及CGLIB动态代理实例和应用外,还会讲解JDK动态代理源码实现过程以及自己写一手个JDK动态代理等.   动态代理在很多底层框架中都会用得到,比如在Sp ...

  3. java动态代理和反射

    反射 1.反射代码详解 通过反射的方式可以获取class对象中的属性.方法.构造函数等,以下是实例: package cn.java.reflect;import java.lang.reflect. ...

  4. 动态代理最全详解系列[2]-Proxy生成代理类对象源码分析

      之前我们通过JDK中的Proxy实现了动态代理,Proxy用起来是比较简便的,但理解起来不是那么清晰,是因为我们并没有看见代理类是怎么生成的,代理类怎么调用的被代理类方法,所以下面我们进入源码看一 ...

  5. JDK动态代理实现原理详解(源码分析)

    无论是静态代理,还是Cglib动态代理,都比较容易理解,本文就通过进入源码的方式来看看JDK动态代理的实现原理进行分析 要了解动态代理的可以参考另一篇文章,有详细介绍,这里仅仅对JDK动态代理做源码分 ...

  6. Java动态数组的用法详解

    Java动态数组是一种可以任意伸缩数组长度的对象,在Java中比较常用的是ArrayList,ArrayList是javaAPI中自带的java.util.ArrayList.下面介绍一下ArrayL ...

  7. Java 动态代理详解 ( 附示例源码,建议收藏)

    动态代理在Java中有着广泛的应用,比如Spring AOP.Hibernate数据查询.测试框架的后端mock.RPC远程调用.Java注解对象获取.日志.用户鉴权.全局性异常处理.性能监控,甚至事 ...

  8. JAVA动态代理详解

    JAVA动态代理详解 问题 1:什么是静态代理,动态代理? 2:动态代理的好处? 什么是静态代理 以生活中例子来看,我作为某某品牌面膜的北京区代理,我替厂家卖面膜,我属于代理,厂家属于委托方. 联系到 ...

  9. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

最新文章

  1. 信息安全系统设计基础第3周学习总结
  2. EMD算法原理与python实现
  3. 炒冷饭系列:设计模式 装饰模式
  4. Java学习之if语句
  5. efcore mysql autofac_Asp.NetCore3.1版本的CodeFirst与经典的三层架构与AutoFac批量注入
  6. NLP之WordCloud:基于jieba+matplotlib库对一段文本生成词云图~~情人节最好的礼物(给你一张过去的词云图,看看那时我们的爱情)
  7. 怎么调整字段长短_木北造型:空气刘海卷发筒怎么用 木北造型告诉您
  8. php去字符串空格,php怎么去掉字符串中空格
  9. LINUX 对引导加密
  10. 多生产者_通知:生产者补贴!打卡时间!定了
  11. win10打印机终结点映射器_用了就回不去?微软官方免费“外挂”,让win10好用到飞起...
  12. I.MX6 Android 设备节点权限
  13. 使用JMeter 进行接口并发性能测试
  14. 2.1 - 递归练习题
  15. 数字图像处理理论课件(清华大学计算机科学与技术系)
  16. 东芝服务器报错误代码维修,实战维修 东芝复印机故障维修详解
  17. 本地项目上传到码云gitee
  18. 京东发力团购欲摘桃 团购市场继续动荡
  19. 酷柚易汛进销存开发进度一览表以及各版本之间区别!
  20. 网页设计之字体设置(上)

热门文章

  1. 闻茂泉:系统性能监控与分析的工程化实践之路
  2. Kafka解析之topic创建(3)——合法性验证
  3. 打造杰出软件开发团队的12条指导建议
  4. 浅谈深浅拷贝问题(这里只针对拷贝构造函数和赋值运算符重载)和简易srting类模拟实现
  5. B站开源自研动漫超分辨率模型,助力动漫UGC视频高清化
  6. LiveVideoStack线上分享第五季(一):企业视频会议场景下的流量分发和弱网优化...
  7. WebRTC直播课堂实践:实时互动是核心
  8. 兰华峰:商业模式驱动企业参与MSU评测
  9. 腾讯TAPD发布2018企业敏捷协作数据报告
  10. 弹性服务器架构-连接一切的力量