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学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理 ...
随机推荐
- 【Nutch2.2.1基础教程之2.2】集成Nutch/Hbase/Solr构建搜索引擎之二:内容分析
请先参见"集成Nutch/Hbase/Solr构建搜索引擎之一:安装及运行",搭建测试环境 http://blog.csdn.net/jediael_lu/article/deta ...
- Tomcat学习笔记 - 错误日志 - Tomcat安装版安装后第二次启动后闪退(转)-- javac不是内部或外部命令 -- 配置java环境教程
如果安装成功并且安装完成第一次启动是成功的,第二次就闪退的话,原因之一是没有配置java的环境.在网上找的配制方法有很多错误,测试javac命令时候会提示不是内部或外部命令,找到一个正确的教程.如下, ...
- jQuery对checkbox的各种操作
//注意: 操作checkbox的checked,disabled属性时jquery1.6以前版本用attr,1.6以上(包含)建议用prop //1.根据id获取checkbox $("# ...
- pubwin2009服务端 修改系统时间方法
所有操作都是必须的,包括重启. 1.建议操作前全体结账,并交班---不结帐的话, 改完时间会出问题的.2.停止pubwin2009服务端 3.将C:\WINDOWS\system32\driver ...
- 改进我们的小游戏 - 零基础入门学习Python004
改进我们的小游戏 让编程改变世界 Change the world by program 改进我们的小游戏 很多鱼油对改善这个游戏提出了建议,小甲鱼做了一下总结,大概有以下几个方面需要改进: 猜错的时 ...
- BC 65 ZYB's Premutation (线段树+二分搜索)
题目简述:有一个全排列,一直每个前缀区间的逆序对数,还原这个排列. fi记录逆序对数,pi记录该位置数值,则k=fi-f(i-1)表示前i-1个数比pi大的数的个数,那么只要在剩余元素求出按大小顺序第 ...
- information_schema.partitions 学习
1.partitions 表中的常用列说明: 1.table_schema:表所在的数据库名 2.table_name:表名 3.partition_method:表分区采用的分区方法 4.parti ...
- Android jar包混淆
具体可参考http://proguard.sourceforge.net/manual/examples.html#library 1.找到android的adt目录下的 D:\soft\adt-bu ...
- 大端模式&小端模式、主机序&网络序、入栈地址高低问题
一.大端模式&小端模式 所谓的“大端模式”,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处 ...
- Linux系统目录/bin /sbin /usr/bin /usr/sbin和/lib /usrlib的一些分析
其实就是相当于转载了. /bin,/sbin,/usr/sbin,/usr/bin 目录 这些目录都是存放命令的,首先区别下/sbin和/bin: 从命令功能来看,/sbin 下的命令属于基本的系统命 ...