时间:2021-05-20
Java 中实例化类的动作,你是否还是一成不变 new 对应对象呢?
经手的项目多了,代码编写量自然会增加,渐渐的会对设计模式产生感觉。
怎样使书写出来的类实例化动作,高内聚,低耦合,又兼具一定的扩展能力呢?
本文试图从几段鲜活的代码入手,给大家呈现不一样的 Java 实例化类。
下面代码取自 com.google.zxing 源码实现:
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints) throws WriterException { Object writer; switch(format.ordinal()) { case 1: writer = new AztecWriter(); break; case 2: writer = new CodaBarWriter(); break; case 3: writer = new Code39Writer(); break; case 4: case 10: case 13: case 14: default: throw new IllegalArgumentException("No encoder available for format " + format); case 5: writer = new Code128Writer(); break; case 6: writer = new DataMatrixWriter(); break; case 7: writer = new EAN8Writer(); break; case 8: writer = new EAN13Writer(); break; case 9: writer = new ITFWriter(); break; case 11: writer = new PDF417Writer(); break; case 12: writer = new QRCodeWriter(); break; case 15: writer = new UPCAWriter(); break; case 16: writer = new UPCEWriter(); } return ((Writer)writer).encode(contents, format, width, height, hints); }其中的 BarcodeFormat 是这样的:
public enum BarcodeFormat { AZTEC, CODABAR, CODE_39, CODE_93, CODE_128, DATA_MATRIX, EAN_8, EAN_13, ITF, MAXICODE, PDF_417, QR_CODE, RSS_14, RSS_EXPANDED, UPC_A, UPC_E, UPC_EAN_EXTENSION; private BarcodeFormat() { }}源码提供的功能是将信息通过几种不同类型条形码 Wirter 输出为位矩阵,然后输出到图片上面,形成随处可见的各种类型的条形码。
BitMatrix bitMatrix = new MultiFormatWriter().encode(_text, BarcodeFormat.QR_CODE, qrcodeWidth, qrcodeHeight, hints);
MatrixToImageWriter.writeToFile(bitMatrix, qrcodeFormat, QrcodeFile);
源码作者在这里使用了JDK 1.5 中引入的新特性 enum 枚举类,编写了BarcodeFormat类,其中定义了不同类型的条形码的属性。
调用 MultiFormatWriter.encode() 根据入参 BarcodeFormat.xx 在枚举类中的序号,来实例化具体的类。
switch(format.ordinal()) { case 1: writer = new AztecWriter(); break; case 2: writer = new CodaBarWriter(); break; case 3: writer = new Code39Writer(); break; ...............这些条形码 Writer 类,同时都实现了抽象接口 Writer 的 两个encode()方法。
具体的条形码 Wirter 类内部根据不同类型的条形码规则,进行不同的逻辑。
使用者不需要过多的关注内部的实现,需要产生什么样子的条形码,入参选用合适的条形码类型即可,笔者上述的例子里面实现的是二维码。
在来看经典 MVC 框架 Webwork 动态实例化类的一段方法代码:
private static Configuration getDefaultConfiguration () { if (defaultImpl == null) { defaultImpl = new DefaultConfiguration(); try { String className = getString("webwork.configuration"); if (!className.equals(defaultImpl.getClass().getName())) { try { defaultImpl = (Configuration) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className)); } catch (Exception e) { LOG.error("Could not instantiate configuration", e); } } return defaultImpl; } catch (IllegalArgumentException localIllegalArgumentException) { } } }源码取自 webwork-core,可能很多看客老爷没有听闻 Webwork, 但是对 Struts 应该是如雷贯耳,Struts2 核心改写自 Webwork。
上述源码提供的功能为实例化用户自己定义的 配置文件读取类,该定义是在配置文件当中。
源码作者在这里使用 Thread.currentThread().getContextClassLoader().loadClass(className) 线程中类加载器,动态实例化自定义配置文件读取类,可谓是效率最高的一种做法。
类加载器的委托链:SystemClassloader -> ExtensionClassloader -> BootstrapClassloader
委派链左边的ClassLoader就可以很自然的使用右边的ClassLoader所加载的类,类加载的机制为判断自已是否加载该类,没有在询问上级。
而这三个类加载器分别对应着编译器去寻找类文件的优先级别和不同的路径:
平时项目中使用的 Class.forname() 会从 BootstrapClassloader 开始询问,是最消耗资源的。
源码作者在这里采用线程类加载器,对应为 SystemClassloader ,效率无疑是最高的。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Java实例化类的方法 Java中,类的实例化方法有四种途径:1)使用new操作符2)调用Class对象的newInstance()方法3)调用clone()
java序列化与ObjectOutputStream和ObjectInputStream的实例详解一个测试的实体类:publicclassParamimplem
Kotlin语言中调用JavaScript方法实例详解Kotlin已被设计为能够与Java平台轻松互操作。它将Java类视为Kotlin类,并且Java也将Ko
Java基础之Filter的实例详解定义:Filter,是Servlet的一种,接口类为javax.servlet.Filter,以一种模块化或者可重用的方法封
详解java中继承关系类加载顺序问题实例代码:/***Createdbyfeion2017/5/31.*/publicclassSonClassextendsP