漫谈Java实例化类

简介:

  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 ,效率无疑是最高的。

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

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

作者:Orson 
出处:http://www.cnblogs.com/java-class/ 
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】 
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】 
如果,您对我的博客内容感兴趣,请继续关注我的后续博客,我是【Orson】 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段 声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

转载:http://www.cnblogs.com/java-class/p/5300313.html

目录
相关文章
|
2天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
3天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
7天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
10 0
|
7天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
11 0
|
9天前
|
安全 Java
append在Java中是哪个类下的方法
append在Java中是哪个类下的方法
21 9
|
9天前
|
JavaScript Java 测试技术
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
25 0
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
|
10天前
|
存储 安全 Java
java多线程之原子操作类
java多线程之原子操作类
|
11天前
|
Java
Java中的异常类总结
Java中的异常类总结
|
11天前
|
Java
Java中的多线程实现:使用Thread类与Runnable接口
【4月更文挑战第8天】本文将详细介绍Java中实现多线程的两种方法:使用Thread类和实现Runnable接口。我们将通过实例代码展示如何创建和管理线程,以及如何处理线程同步问题。最后,我们将比较这两种方法的优缺点,以帮助读者在实际开发中选择合适的多线程实现方式。
19 4
|
12天前
|
Java
在Java中,多态性允许不同类的对象对同一消息做出响应
【4月更文挑战第7天】在Java中,多态性允许不同类的对象对同一消息做出响应
17 2