JAVA编程思想——类型信息(反射)
一、反射与RTTI
RTTI:这个类型必须在编译的时候已知或者存在,如果不知道对象的确切类型,RTTI可以告诉你。
反射(个人认为就是能够利用Class获取或者调用.class这个文件中的数据):当我们从程序外(网络,磁盘中)在程序运行的时候获取这些数据,发现这些数据是个类,并且不知道该类的类型,那么我们怎么使用这些数据呢。
所以说根本区别是:RTTI在编译的时候会检查和打开.class文件,但是在反射中.class文件是不可获取的,所以在运行时打开和检查.class文件
二、使用
利用反射获取类的方法和构造方法
- ublic class UseReflection {
- public static void main(String[]args){
- try {
- Class c = Class.forName("String");
- Method[]methods = c.getMethods();//获取c这个对象的所有方法
- Constructor[]constructors = c.getConstructors();//获取c这个对象的所有构造方法
- for (Method method:methods){
- method.toString();
- constructors.toString();
- }
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
View UseReflection
三、动态代理
①、代理
作用:将额外的操作从“实际”对象中分离到不同的地方。(特别是当有时候准备使用这个功能,有时候又不需要使用这个功能的时候,这就很容易修改)。
(感觉就是扩展了这个方法,但是又不是直接在方法内增加,并且还能够选择用或者不用)
步骤:1、将需要的操作封装为一个接口 2、主类继承这个接口,然后实现 3、创建代理继承接口,然后获取主类,在实现方法的时候,调用新方法然后再调用主类的同样的方法。
- public interface Proxy {
- void doSomething();
- void somethingElse(String make);
- }
代理接口
- //主类继承了代理类,并重写了该方法
- public class Child implements Proxy{
- @Override
- public void doSomething() {
- // TODO Auto-generated method stub
- System.out.println("Play");
- }
- @Override
- public void somethingElse(String make) {
- // TODO Auto-generated method stub
- System.out.println("eat fruit");
- }
- }
主类
- //代理类,继承了代理接口,并获取主类对象向上转型为代理,然后在相应方法内,重新调用
- public class SimpeProxy implements Proxy{
- private Proxy mProxy;
- public SimpeProxy(Proxy proxy){
- mProxy = proxy;
- }
- @Override
- public void doSomething() {
- // TODO Auto-generated method stub
- System.out.println("Footboll");
- //调用主类的该方法
- mProxy.doSomething();
- }
- @Override
- public void somethingElse(String make) {
- // TODO Auto-generated method stub
- System.out.println("Footboll"+make);
- mProxy.somethingElse(make);
- }
- }
代理类
- public class AchieveProxy {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- complete(new Child());//未使用代理
- complete(new SimpeProxy(new Child()));//使用代理
- }
- public static void complete(Proxy proxy){
- proxy.doSomething();
- proxy.somethingElse("make cake");
- }
- }
实现逻辑类
②、动态代理
使用:1、用到的类:InvocationHandler接口,和Proxy类
步骤:1、同样将需要的操作封装成一个接口 2、创建相关类并继承接口 3、创建代理类,该类继承InvocationHandler接口,实现invoke()方法,该方法实现代理的逻辑。
4、在主线程中调用代理
示例:
代理接口和主类不变就不写了。
- //继承接口
- public class DynamicProxy implements InvocationHandler {
- private Object mChild;
- public DanamicProxy(Object child){
- mChild = child;
- }
- //实现接口的方法。
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // TODO Auto-generated method stub
- System.out.println("我是代理,大家好"+"proxy "+proxy.getClass().getSimpleName());
- //绑定该方法,参数1、是被被代理对象 参数2、是传送到该方法的值
- return method.invoke(mChild, args);
- }
- }
- /*
- *方法的使用原理:参数1、当前的代理对象 参数2、正在被使用的方法 参数3、对于该方法传入的参数。
- *
- */
DynaicProxy
- //创建被代理对象
- Child child = new Child();
- //创建代理对象
- DanamicProxy dana = new DanamicProxy(child);
- //连接代理与被代理对象 参数1、获取类加载器 参数2、获取代理的接口 参数3、获取代理对象
- Proxy proxy = (Proxy)java.lang.reflect.Proxy.newProxyInstance(child.getClass().getClassLoader(), new Class[]{Proxy.class}, dana);
- //调用代理对象的方法
- complete(proxy);
- public static void complete(Proxy proxy){
- proxy.doSomething();
- proxy.somethingElse("make cake");
- }
实现逻辑
原理:Proxy类通过反射获取接口的方法,在继承InvcationHandler的类中,当代理调用接口的方法的时候,就会触发invoke()方法,并将用到的方法和参数传入,然后再用用到的方法调用invoke()调用被代理类的相应方法。
动态代理的优点:①、只需要在invoke()中实现逻辑就可以了,不用因为有多个方法需要代理,就需要重写一堆方法。 ②、代理可以被多个类使用,而不是继承特定接口的类。
最近用到的Retrofit应该就是用到了动态代理。
RTTI的新发现:
- Child child = new Child();
- Proxy proxy = (Proxy)child;
- System.out.println(proxy.getClass().getName());
- //答案居然是Child。 说明反射是根据指针来的,向上转型无法改变其name
JAVA编程思想——类型信息(反射)的更多相关文章
- Java编程思想——类型信息(RTTI)
一.概念 编译时已知的到所有的类型:就是在写代码阶段就确定是这个类型了,当运行程序的时候,类型是不可改变的 举例:List<String> str = new ArrayList(); ...
- 【Java编程思想笔记】反射
文章参考:学习网站 how2java.cn 参考博客:(敬业的小码哥)https://blog.csdn.net/sinat_38259539/article/details/71799078 (青色 ...
- Java 编程思想 Chapter_14 类型信息
本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...
- 【Java核心技术】类型信息(Class对象 反射 动态代理)
1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有“常规”对象的,J ...
- JAVA类型信息——反射机制
JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...
- java编程思想-枚举类型思维导图
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
- 注解的基本盘点 -- 《Java编程思想》
注解(元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在之后的某一个时刻非常方便地使用这些数据. ---<Java编程思想> 其实注解可以理解为一个工具类,只要使用了这个工 ...
- java编程思想
Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...
随机推荐
- ORACLE11G常用函数
1 单值函数 1.1 日期函数 1.1.1 Round [舍入到最接近的日期](day:舍入到最接近的星期日) select sysdate S1, round(sysdate) S2 , round ...
- You and your research
英文版http://www.cs.virginia.edu/~robins/YouAndYourResearch.html 视频版http://www.youtube.com/watch?v=a1zD ...
- 给兄弟说下如何处理Debian下常见的apache2的几个问题
这段时间总是有兄弟问到在linux下的apache2配置,其实很简单,这里统一答复下. 一.安装 当然是apt-get install 最简单了, 顺便把php5和GD什么的一起装上吧,基本上不用配置 ...
- IIC的标准操作函数集(C51)包含C和H文件
/********************************************************************* 头文件名 VIIC_C51.H 这个头文件对应的库是VII ...
- 8051_asm.uew
/L20"8051 Assembly" AASM_LANG Line Comment = ; Nocase String Chars = ' File Extensions = S ...
- cf479D Long Jumps
D. Long Jumps time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- PhpEclipse插件
PHP开发工具 PHPEclipse PHPEclipse 是一个相当强大的一个Eclipse下开发PHP的插件,包括的功能有:PHP语法分析,调试,代码格式化,大纲视图,代码模板定制等. 安装地址: ...
- Word Search 解答
Question Given a 2D board and a word, find if the word exists in the grid. The word can be construct ...
- 剑指offer-面试题10:二进制中1的个数
题目:请实现一个函数,输入一个函数,输出该数二进制表示中1的个数.例如把9 表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 这道题最典型的方法就是用移位统计,就比如统计9的二进制1 ...
- telnet 命令使用详解
1..关于NTLM验证由于Telnet功能太强大,而且也是入侵者使用最频繁的登录手段之一,因此微软公司为Telnet添加了身份验证,称为NTLM验证,它要求Telnet终端除了需要有Telnet服务主 ...