漫谈 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/p/5300313.html,如需转载请自行联系原作者

相关文章
|
2月前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
45 6
|
17天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
39 8
|
1月前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
51 17
|
26天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
86 4
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
49 2
|
1月前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
41 4
|
1月前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
40 5
|
1月前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
67 5
|
1月前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
37 3