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. MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息

    Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...

  2. JavaScript(六)——实现图片上下或者左右无缝滚动

    /*! jQuery v1.8.3 jquery.com | jquery.org/license */ (function(e,t){function _(e){var t=M[e]={};retu ...

  3. Sql Server之旅——第十三站 对锁的初步认识

    终于这个系列快结束了,马上又要过年了,没什么心情写博客...作为一个开发人员,锁机制也是我们程序员必须掌握的东西,很久之前 在学习锁的时候,都是教科书上怎么说,然后我怎么背,缺少一个工具让我们眼见为实 ...

  4. 【故障处理】一次RAC故障处理过程

    [故障处理]一次RAC故障处理过程 1.1  故障环境介绍 项目 source db db 类型 2节点RAC db version 11.2.0.1.0 db 存储 ASM OS版本及kernel版 ...

  5. 字典dictionary

    字典,即我们可以通过索引来查找更详细的内容.每个item都是由一对index:value构成的 索引可以有副本,但是试图根据存在副本的索引访问元素时,只会取最靠后的那个. 索引必须是immutable ...

  6. SpringMvc-Httl-shiro的整合

    来到新的公司一个月,以前实习公司的用的是srping+hibernate+struts2,而在这里不在用的这些了,而是用的springMVC和jdbc模板来操作数据了,所以又用了一段时间去慢慢融入这个 ...

  7. 工作中常用的Linux命令:ipcs/ipcrm命令

    本文链接:http://www.cnblogs.com/MartinChentf/p/6057100.html (转载请注明出处) ipcs 1. 命令格式 ipcs [resource-option ...

  8. ES6 Set/WeakSet

    ES6里加入了一个新数据解构Set,和Java的Set一样,它里面不存放重复的元素.Set实现为一个类,使用时需要先new. var s1 = new Set() s1.add(1) s1.add(2 ...

  9. union all 与order by的连用

    昨天工作过程中发现一个奇怪的地方: 代码段A: 1---select   *  from  table1 2---order  by  no 3---union  all 4---select   * ...

  10. css3常用动画+动画库

    一.animates.css animate.css是来自dropbox的工程师Daniel Eden开发的一款CSS3的动画效果小类库.包含了60多款不同类型的CSS3动画,包括:晃动,闪动,各种淡 ...