一、反射与RTTI

RTTI:这个类型必须在编译的时候已知或者存在,如果不知道对象的确切类型,RTTI可以告诉你。

反射(个人认为就是能够利用Class获取或者调用.class这个文件中的数据):当我们从程序外(网络,磁盘中)在程序运行的时候获取这些数据,发现这些数据是个类,并且不知道该类的类型,那么我们怎么使用这些数据呢。

所以说根本区别是:RTTI在编译的时候会检查和打开.class文件,但是在反射中.class文件是不可获取的,所以在运行时打开和检查.class文件

二、使用

利用反射获取类的方法和构造方法

  1. ublic class UseReflection {
  2. public static void main(String[]args){
  3. try {
  4. Class c = Class.forName("String");
  5. Method[]methods = c.getMethods();//获取c这个对象的所有方法
  6. Constructor[]constructors = c.getConstructors();//获取c这个对象的所有构造方法
  7. for (Method method:methods){
  8. method.toString();
  9. constructors.toString();
  10. }
  11. } catch (ClassNotFoundException e) {
  12. // TODO Auto-generated catch block
  13. e.printStackTrace();
  14. }
  15.  
  16. }
  17. }

View UseReflection

三、动态代理

①、代理

作用:将额外的操作从“实际”对象中分离到不同的地方。(特别是当有时候准备使用这个功能,有时候又不需要使用这个功能的时候,这就很容易修改)。

(感觉就是扩展了这个方法,但是又不是直接在方法内增加,并且还能够选择用或者不用)

步骤:1、将需要的操作封装为一个接口 2、主类继承这个接口,然后实现 3、创建代理继承接口,然后获取主类,在实现方法的时候,调用新方法然后再调用主类的同样的方法。

  1. public interface Proxy {
  2. void doSomething();
  3. void somethingElse(String make);
  4. }

代理接口

  1. //主类继承了代理类,并重写了该方法
  2. public class Child implements Proxy{
  3.  
  4. @Override
  5. public void doSomething() {
  6. // TODO Auto-generated method stub
  7. System.out.println("Play");
  8. }
  9.  
  10. @Override
  11. public void somethingElse(String make) {
  12. // TODO Auto-generated method stub
  13. System.out.println("eat fruit");
  14. }
  15.  
  16. }

主类

  1. //代理类,继承了代理接口,并获取主类对象向上转型为代理,然后在相应方法内,重新调用
  2. public class SimpeProxy implements Proxy{
  3. private Proxy mProxy;
  4.  
  5. public SimpeProxy(Proxy proxy){
  6. mProxy = proxy;
  7. }
  8.  
  9. @Override
  10. public void doSomething() {
  11. // TODO Auto-generated method stub
  12. System.out.println("Footboll");
  13. //调用主类的该方法
  14. mProxy.doSomething();
  15. }
  16.  
  17. @Override
  18. public void somethingElse(String make) {
  19. // TODO Auto-generated method stub
  20. System.out.println("Footboll"+make);
  21. mProxy.somethingElse(make);
  22. }
  23.  
  24. }

代理类

  1. public class AchieveProxy {
  2.  
  3. public static void main(String[] args) {
  4. // TODO Auto-generated method stub
  5. complete(new Child());//未使用代理
  6. complete(new SimpeProxy(new Child()));//使用代理
  7. }
  8.  
  9. public static void complete(Proxy proxy){
  10. proxy.doSomething();
  11. proxy.somethingElse("make cake");
  12. }
  13. }

实现逻辑类

②、动态代理

使用:1、用到的类:InvocationHandler接口,和Proxy类

步骤:1、同样将需要的操作封装成一个接口 2、创建相关类并继承接口   3、创建代理类,该类继承InvocationHandler接口,实现invoke()方法,该方法实现代理的逻辑。

4、在主线程中调用代理

示例:

代理接口和主类不变就不写了。

  1. //继承接口
  2. public class DynamicProxy implements InvocationHandler {
  3. private Object mChild;
  4. public DanamicProxy(Object child){
  5. mChild = child;
  6. }
  7. //实现接口的方法。
  8. @Override
  9. public Object invoke(Object proxy, Method method, Object[] args)
  10. throws Throwable {
  11. // TODO Auto-generated method stub
  12.  
  13. System.out.println("我是代理,大家好"+"proxy "+proxy.getClass().getSimpleName());
  14. //绑定该方法,参数1、是被被代理对象 参数2、是传送到该方法的值
  15. return method.invoke(mChild, args);
  16. }
  17. }
  18. /*
  19. *方法的使用原理:参数1、当前的代理对象 参数2、正在被使用的方法 参数3、对于该方法传入的参数。
  20. *
  21. */

DynaicProxy

  1. //创建被代理对象
  2. Child child = new Child();
  3. //创建代理对象
  4. DanamicProxy dana = new DanamicProxy(child);
  5. //连接代理与被代理对象 参数1、获取类加载器 参数2、获取代理的接口 参数3、获取代理对象
  6. Proxy proxy = (Proxy)java.lang.reflect.Proxy.newProxyInstance(child.getClass().getClassLoader(), new Class[]{Proxy.class}, dana);
  7. //调用代理对象的方法
  8. complete(proxy);
  9.  
  10. public static void complete(Proxy proxy){
  11. proxy.doSomething();
  12. proxy.somethingElse("make cake");
  13. }

实现逻辑

原理:Proxy类通过反射获取接口的方法,在继承InvcationHandler的类中,当代理调用接口的方法的时候,就会触发invoke()方法,并将用到的方法和参数传入,然后再用用到的方法调用invoke()调用被代理类的相应方法。

动态代理的优点:①、只需要在invoke()中实现逻辑就可以了,不用因为有多个方法需要代理,就需要重写一堆方法。  ②、代理可以被多个类使用,而不是继承特定接口的类。

最近用到的Retrofit应该就是用到了动态代理。

RTTI的新发现:

  1. Child child = new Child();
  2. Proxy proxy = (Proxy)child;
  3. System.out.println(proxy.getClass().getName());
  4. //答案居然是Child。 说明反射是根据指针来的,向上转型无法改变其name

JAVA编程思想——类型信息(反射)的更多相关文章

  1. Java编程思想——类型信息(RTTI)

    一.概念 编译时已知的到所有的类型:就是在写代码阶段就确定是这个类型了,当运行程序的时候,类型是不可改变的 举例:List<String> str = new ArrayList();   ...

  2. 【Java编程思想笔记】反射

    文章参考:学习网站 how2java.cn 参考博客:(敬业的小码哥)https://blog.csdn.net/sinat_38259539/article/details/71799078 (青色 ...

  3. Java 编程思想 Chapter_14 类型信息

    本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...

  4. 【Java核心技术】类型信息(Class对象 反射 动态代理)

    1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有“常规”对象的,J ...

  5. JAVA类型信息——反射机制

    JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...

  6. java编程思想-枚举类型思维导图

  7. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  8. 注解的基本盘点 -- 《Java编程思想》

    注解(元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在之后的某一个时刻非常方便地使用这些数据. ---<Java编程思想> 其实注解可以理解为一个工具类,只要使用了这个工 ...

  9. java编程思想

    Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...

随机推荐

  1. ORACLE11G常用函数

    1 单值函数 1.1 日期函数 1.1.1 Round [舍入到最接近的日期](day:舍入到最接近的星期日) select sysdate S1, round(sysdate) S2 , round ...

  2. You and your research

    英文版http://www.cs.virginia.edu/~robins/YouAndYourResearch.html 视频版http://www.youtube.com/watch?v=a1zD ...

  3. 给兄弟说下如何处理Debian下常见的apache2的几个问题

    这段时间总是有兄弟问到在linux下的apache2配置,其实很简单,这里统一答复下. 一.安装 当然是apt-get install 最简单了, 顺便把php5和GD什么的一起装上吧,基本上不用配置 ...

  4. IIC的标准操作函数集(C51)包含C和H文件

    /********************************************************************* 头文件名 VIIC_C51.H 这个头文件对应的库是VII ...

  5. 8051_asm.uew

    /L20"8051 Assembly" AASM_LANG Line Comment = ; Nocase String Chars = ' File Extensions = S ...

  6. cf479D Long Jumps

    D. Long Jumps time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  7. PhpEclipse插件

    PHP开发工具 PHPEclipse PHPEclipse 是一个相当强大的一个Eclipse下开发PHP的插件,包括的功能有:PHP语法分析,调试,代码格式化,大纲视图,代码模板定制等. 安装地址: ...

  8. Word Search 解答

    Question Given a 2D board and a word, find if the word exists in the grid. The word can be construct ...

  9. 剑指offer-面试题10:二进制中1的个数

    题目:请实现一个函数,输入一个函数,输出该数二进制表示中1的个数.例如把9 表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 这道题最典型的方法就是用移位统计,就比如统计9的二进制1 ...

  10. telnet 命令使用详解

    1..关于NTLM验证由于Telnet功能太强大,而且也是入侵者使用最频繁的登录手段之一,因此微软公司为Telnet添加了身份验证,称为NTLM验证,它要求Telnet终端除了需要有Telnet服务主 ...