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()方法。
  • public interface Writer {
    BitMatrix encode(String var1, BarcodeFormat var2, int var3, int var4) throws WriterException; BitMatrix encode(String var1, BarcodeFormat var2, int var3, int var4, Map<EncodeHintType, ?> var5) throws WriterException;
    }
  • 具体的条形码 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所加载的类,类加载的机制为判断自已是否加载该类,没有在询问上级。
  • 而这三个类加载器分别对应着编译器去寻找类文件的优先级别和不同的路径:
  • BootClassLoader  由C++编写的,从 %jre%/lib 目录中加载类,或者运行时用 -Xbootclasspath 指定目录来加载。是编译器最优先寻找 class 的地方
  • ExtClassLoader  从 %jre%/lib/ext 目录加载类,或者运行时用 -Djava.ext.dirs 制定目录来加载。是编译器次优先寻找 class 的地方
  • SystemClassloader 也就是我们常说的 AppClassloader ,它对应当前路径,所以也是编译器默认找 class 的地方。
  • 平时项目中使用的 Class.forname() 会从 BootstrapClassloader 开始询问,是最消耗资源的。
  • 源码作者在这里采用线程类加载器,对应为 SystemClassloader ,效率无疑是最高的。

夜已经深了,看客老爷看完之后是否有一点点的感觉呢。

如果你不喜欢将世间万物抽象到计算机的世界,或许程序员只是你谋生的手段,你可能体会不到代码的美丽。

漫谈 Java 实例化类的更多相关文章

  1. Java的类的实例化顺序

    Java的类的实例化顺序 父类的静态数据 子类的静态数据 父类的成员变量 父类的构造方法 子类的成员变量 子类的构造方法

  2. 创建java类并实例化类对象

    创建java类并实例化类对象例一1.面向对象的编程关注于类的设计2.设计类实际上就是设计类的成员3.基本的类的成员,属性(成员变量)&方法 面向对象思想的落地法则一:1.设计类,并设计类的成员 ...

  3. JAVA 创建类,使用类

    一.创建类: Test.java //定义类 public class Test{ //属性 String name; String gender; int age; //方法,无参无返回 publi ...

  4. java 实例化是调用了子类重写方法

    java 实例化时调用了抽象方法或者class里面某个方法,如果子类有重写改方法,实际运行的是子类重写方法 package auto.test; //抽象父类 public abstract clas ...

  5. 【Demo 0004】Java基础-类封装性

    本章学习要点:       1.  Java封装特性;       2.  掌握类的定义:       3.  掌握类的调用方法; 一.封装特性        Java 纯面向对象语言,面向对象语言遵 ...

  6. java实例化对象

    摘要:分享牛,分享牛分享,java类加载机制,java实例化对象,java实例化对象机制,java基础. java是如何实例化对象的呢?以及实例化对象的先后顺序是什么?下面我们以测试的方式说明. 1. ...

  7. 第31节:Java基础-类与对象

    前言 Java基础-类与对象,方法的重载,构造方法的重载,static关键字,main()方法,this关键字,包,访问权限,类的继承,继承性,方法的重写,super变量. 方法的重载:成员方法的重载 ...

  8. java的类继承(与c++对比)

    1. interface的引入 使用interface来定义某一类通用操作,而又不强制规定其实现,对于Java的流行真是太重要了. 以JDBC举例.在Java之前,C++与数据库建立连接,常用的一个技 ...

  9. Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?

    本文使用工具和全部源码下载: http://download.csdn.net/detail/sunylat/8190765 为什么我们要在Delphi XE7的安卓程序调用JAVA的JAR,使用JA ...

随机推荐

  1. Java AIO 异步IO应用实例

    项目地址:https://github.com/windwant/aio-test Server: package org.windwant.aio; import java.io.IOExcepti ...

  2. 【SQL篇章】【SQL语句梳理 :--基于MySQL5.6】【已梳理:ALTER TABLE解析】

    ALTER TABLE 解析实例: SQL: 1.增加列 2.增加列,调整列顺序 3.增加索引 4.增加约束 5.增加全文索引FULL-TEXT 6.改变列的默认值 7.改变列名字(类型,顺序) 8. ...

  3. Java代码获取NTP服务器时间

    apache的commons-net包下面有ntp相关的实现类,主要类有: 1  org.apache.commons.net.ntp.NTPUDPClient ? 1  org.apache.com ...

  4. (六)责任链模式-C++实现

    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 责任链模式是使用多个对象处理用户请求的成熟模式,它的关键 ...

  5. string、math类、random随机数、datetime、异常保护

    今天讲的知识点比较多,比较杂,以至于现在脑子里还有点乱,慢慢来吧... string (1)string.length; (获得你string字符串的长度) (2)a = a.Trim(); 重新赋值 ...

  6. python反弹tty shell

    linux环境下进行内外渗透需要反弹shell连接内网ssh,Telnet等,就需要tty层的shell了.python代码转过来的,备用. #!/usr/bin/python import sys ...

  7. ie9及以下不兼容event.target.dataset对象

    ie9及以下不兼容event.target.dataset对象,请使用event.target.getAttribute('data-xxx')

  8. 用css画实心三角形

    .arrow-down:after{ content: ''; position: relative; top: 12px; left: 2px; border-style: solid; borde ...

  9. IIS7.5上的REST服务的Put操作发生HTTP Error 405.0 - Method Not Allowed 解决方法

    WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...

  10. [Cache] C#操作缓存--CacheHelper缓存帮助类 [复制链接]

    using System;using System.Web;using System.Collections; namespace DotNet.Utilities{ public class Cac ...