Java Apache Commons Collection3.2.1 理解Transformer 接口
Java Apache Commons Collection3.2.1 理解Transformer 接口
- 引言
- Transformer 接口
- InvokerTransformer
- MapTransformer 和 ConstantTransformer
- ChainedTransformer
- Runtime
- 执行命令
- 反射调用
- 尝试使用Transformer调用
- InvokerTransformer小栗子
- MapTransformer 小栗子
- ChainedTransformer 链式调用
引言
好久没写JAVA文章了,写一篇基础,序列化和反序列化基础应该都好理解,这次讲的是Java Apache Commons Collection
中的Transformer
。
Transformer 接口
org.apache.commons.collections.Transformer
接口开始分析
public interface Transformer {public Object transform(Object input);
}
- Transforms the input object (leaving it unchanged) into some output object.
- @param input the object to be
transformed
, should be left unchanged - @return a transformed object
它说传入的对象会被转换
,并返回转换后的对象
记住了,转换器
就是用来转换对象
用的,在这里你可以先简单的当它是一个特殊的工厂
。
实现此接口的类有下面这些:
比如有一些有趣的Transformer
,我们看看它们的transform
方法
InvokerTransformer
Class cls = input.getClass();Method method = cls.getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);
它将返回invoke后的对象
,其中iMethodName成员
和iParamTypes成员
在其构造函数
传入
MapTransformer 和 ConstantTransformer
//private final Map iMap;
return iMap.get(input);
它将返回iMap中input对象为key的值
,其中iMap参数
在其构造函数
传入,有趣的是它的getInstance
用到了ConstantTransforme
public static Transformer getInstance(Map map) {if (map == null) {return ConstantTransformer.NULL_INSTANCE;}return new MapTransformer(map);}
ConstantTransformer
的transform
方法,其实什么都没有做
,它返回的就是一直都是iConstant成员
,其中iConstant成员
在其构造函数传入。
public Object transform(Object input) {//根本没有用到inputreturn iConstant;
}
ChainedTransformer
ChainedTransformer
的transform
方法,比起之前的稍微有些复杂
public Object transform(Object object) {for (int i = 0; i < iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
其iTransformers
是一个Transformer数组
,也就是说它根据数组中的Transformer
(其中可能包含很多不同的Transformer),遍历得到每个Transformer
然后依次转换
为一个Object
,并且将这个Object
传入数组的下一个Transformer
进行转换
。
我们看看它的2个getInstance
方法,代码贴在下面,我们可以看见要么传入一个数组,要么传入2个Transformer,它会帮我们拼接为数组,其实它还有一个public static Transformer getInstance(Collection transformers)
,我没有将它贴在下面,因为他本质上和传入数组干的事情没什么区别。
private final Transformer[] iTransformers;public static Transformer getInstance(Transformer[] transformers) {FunctorUtils.validate(transformers);if (transformers.length == 0) {return NOPTransformer.INSTANCE;}transformers = FunctorUtils.copy(transformers);return new ChainedTransformer(transformers);
}public static Transformer getInstance(Transformer transformer1, Transformer transformer2) {if (transformer1 == null || transformer2 == null) {throw new IllegalArgumentException("Transformers must not be null");}Transformer[] transformers = new Transformer[] { transformer1, transformer2 };return new ChainedTransformer(transformers);
}//构造函数
public ChainedTransformer(Transformer[] transformers) {super();iTransformers = transformers;
}
Runtime
Runtime
运行时,每个语言都有,比如C/C++的CRT/GLIBC,它的意思很简单,就是运行时,更细的解释应该说是运行时支持库和运行时环境,众所周知一般程序员使用C/C++开发应用层或者基于系统的驱动时,使用的Runtime大多都是标准库,它们是背靠操作系统的,而Java,C#,Python,Lua等等语言都是有自己的虚拟机的,我们想让系统执行一个命令,只有通过虚拟机来和操作系统打交道,因为操作系统本身根本不认识你的字节码。而虚拟机提供的Runtime中,存在了很多native方法,它们是由C/C++编写的,依靠操作系统的。
执行命令
如果我们想调用Runtime.getRuntime
通过运行时执行命令,那么我们直观的代码应该是下面这样:
Runtime.getRuntime().exec("calc"); //执行一个calc,弹出一个计算器
反射调用
反射的基础就不在这里写了,我们如果要通过反射来调用,会写成下面这样:
Method getRuntime = Runtime.class.getMethod("getRuntime");
Object runtime = getRuntime.invoke(Runtime.class);
if (runtime instanceof Runtime){((Runtime) runtime).exec("calc");
}
或者更为复杂的
Method getRuntime = Runtime.class.getMethod("getRuntime");Method exec = Runtime.class.getMethod("exec", String.class);Object runtime = getRuntime.invoke(Runtime.class);if (runtime instanceof Runtime){exec.invoke(runtime,"calc");}
尝试使用Transformer调用
InvokerTransformer小栗子
举个最简单的例子,我们用InvokerTransformer
来弹出一个计算器。
InvokerTransformer
的getInstance
方法上面并没有贴代码,简单的说就是
第一个参数值methodName
,第二个参数是对应methodName方法
的参数类型
,第三个参数就是对应methodName方法
的参数本身
。
Runtime runtime = Runtime.getRuntime();
Transformer transformer = InvokerTransformer.getInstance("exec", new Class[]{String.class}, new String[]{"calc"});
transformer.transform(runtime);
我们成功的弹了一个计算器。
MapTransformer 小栗子
只是举一个简单的例子
HashMap<String,Object> map = new HashMap<>();map.put("key",Runtime.getRuntime());Transformer transform = MapTransformer.getInstance(map);Runtime runtime = (Runtime) transform.transform("key");runtime.exec("calc");
ChainedTransformer 链式调用
Transformer[] transformers = {InvokerTransformer.getInstance("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),InvokerTransformer.getInstance("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),InvokerTransformer.getInstance("exec", new Class[]{String.class}, new String[]{"calc"})
};
Transformer chainedTransformer = ChainedTransformer.getInstance(transformers);
chainedTransformer.transform(Runtime.class);
这个稍微有些复杂,我们先来分析一下
第一个InvokerTransformer
,为什么我们不直接调用getRuntime
,而是调用了getMethod
?我们看InvokerTransformer#transform
方法
Class cls = input.getClass();Method method = cls.getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);
它本身通过反射调用,如果
其中method
是通过input.getMethod
调用而不是input.getClass().getMethod
,是没有任何问题的,问题出在Class cls = input.getClass();
其中input.getClass()
也就是Runtime.class.getClass()
,它会变成java.lang.Class
,也就是直接获取getRuntime
根本拿不到。
所以第一个InvokerTransformer
算是做了一个反射套娃
,本身含义如下:
Class cls = Runtime.class.getClass();
Method method = cls.getMethod("getMethod", String.class, Class[].class);
Method getRuntimeMethod = (Method) method.invoke(Runtime.class, "getRuntime", null);
//注意此时还是一个Method对象,并不是Runtime
第二个InvokerTransformer
就等于拿到了runtime
对象了,后面也就很简单了。
//第二个InvokerTransformer做的事
Class cls = getRuntimeMethod.getClass();
Method method = cls.getMethod("invoke", Object.class, Object[].class);
Runtime runtime = (Runtime) method.invoke(getRuntimeMethod,null,null);
Java Apache Commons Collection3.2.1 理解Transformer 接口相关推荐
- commons-math3-3.6.1-org.apache.commons.math3.analysis.differentiation-包下的接口-中英对照文档及源码赏析
commons-math3-3.6.1-org.apache.commons.math3.analysis.differentiation-包下的接口-中英对照文档及源码赏析 摘要:中英对照文档.源码 ...
- java Apache Commons jar包简介
一.Commons BeanUtils 说明:针对Bean的一个工具集.由于Bean往往是有一堆get和set组成,所以BeanUtils也是在此基础上进行一些包装. 二.Commons CLI 说明 ...
- Apache java文件比对,Java Apache Commons的字符串比较
1、使用Apache Commons的equals()实现字符串比较 StringUtils类的equals()方法是String类方法equals()的增强版,它会处理null值:assertTha ...
- java apache commons_使用java apache commons下载文件?
如果您正在寻找一种获取下载前总字节数的方法,您可以从http响应中的Content-Length头部获取此值. 如果您只想在下载后的最终字节数,最简单的方法是检查您要写入的文件大小. 但是,如果要显示 ...
- java apache commons_Apache commons(Java常用工具包)简介
Apache Commons是一个非常有用的工具包,解决各种实际的通用问题,下面是一个简述表,详细信息访问http://jakarta.apache.org/commons/index.html Be ...
- 一篇关于apache commons类库的详解
1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...
- Apache工具库——Apache Commons的使用
Apache Commons是Apache开源的一个java组件库,其中包含了大量子项目,其中常用的组件有: 组件 功能介绍 BeanUtils 提供了对于JavaBean进行各种操作,克隆对象,属性 ...
- Apache Commons Collections包和简介
背景介绍 Apache Commons是Apache软件基金会的项目,曾经隶属于Jakarta项目.Commons的目的是提供可重用的.解决各种实际的通用问题且开源的Java代码.Commons由三部 ...
- Apache Commons 工具类介绍及简单使用(转)
转自:http://www.cnblogs.com/younggun/p/3247261.html Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下 ...
最新文章
- java raw_GitHub - Braw115/JavaWEB: JavaWEB学习之中的一些Demo
- HTML中的div标签
- python - work3
- microservices kubernetes
- C语言课后习题(26)
- 手机modem开发(9)---LTE注网总体流程
- 项目启动会ppt_项目经理实战篇-项目启动会
- 如何开发Linux内核?
- wangeditor react中使用
- 沙盘 服务器未响应,为什么沙盘总是服务启动失败
- binary 和 varbinary 用法全解
- 4170万元人民币的 绿坝 花季护航 预装1年软件,到底值不值
- Reeder for Chrome:让 Google Reader 更加简洁美观
- 数据库,万能密码与密码解析
- 小小技巧--BLOB视频加密
- 谷歌浏览器flash插件离线下载,最新版
- android 三点参数,iqoo3参数配置详情-iqoo3参数配置手机参数详细表
- Arduino开发板利用L298N电机驱动模块驱动直流电机
- img下方出现空隙的原因及解决办法
- 结巴分词--关键词抽取