004:通过私有构造器强化不可实例化的能力

工具类:只含有静态方法和静态域的类java.lang.Mathjava.util.Arrays,把宗旨类型或数组类型上的连带措施组织起来。java.util.Collections把贯彻特定接口的靶子上的静态方法组织起来。利用这体系把final类上的办法组织起来,以代替扩充该类的做法。

  独有当类不包蕴显式的构造器时,编写翻译器才会生成贰个国有的、无参的缺省构造器。只要让二个类蕴含个人构造器,那么些类就不可能被实例化了。示例:

编纂只含有静态方法和静态域的类非常受诟病,因为微微人在面向对象的语言中滥用那样的类来编排进程化的次第。但在创立工具类的时候,大部分是不必要实例化的,并且实例化他们也从未意义,在这种景观下须求确认保证该类是不可实例化的。

第四条:通过个人构造器强化不可实例化的力量


工具类(utils)不期望被实例化,只提供一些static方法方便操作。该怎么做?

那样的工具类不期望被实例化,实例化对它们从不其余意义。

1 // 工具类
2 public class UtilityClass {
3     // 私有构造器
4     private UtilityClass {
5         throw new AssertionError();
6     }
7     
8     // 其他操作...
9 }

留存难点:
在创设不可实例化的类时,即便并未有定义构造器,编写翻译器会自行提供一个国有的、无参的缺省构造器(default
constructor),顾客端依然能够实例化它,而且能够三番五次该类并经超过实际例化子类来兑现实例化;

1. 简介

有个别时候,大家须要编写制定一些只富含静态方法的类,那样的类的实例化是从未别的意义的。所以大家供给把那个类的构造器设置为私家的。

  • 1、将类做成抽象类来强制该类不可被实例化。
    明明十二分,因为类能够被子类化,而且该子类能够被实例化,以致会误导顾客,感到这些抽象类特地为了承接而设计的。

  • 2、手动注明私有构造器,替代暗中认可的无参公有结构。
    出于构造器是私有的,所以不得以在此类的外表访问他,不过她可以通过反射可能本身类内部去new,能够在构造器内部直接抛出极度,并在代码中追加一条注释。如下:

准备通过将类做成抽象类来强制该类不可被实例化,那是无用的。该类能够被子类化,何况该子类能够被实例化。那样会误导客户,认为那种类是专程为了承袭而规划的。

  AssertionError幸免在类的内部调用构造器,保障此类在任何情状下都不会被实例化。同期,这几个类不可能被子类化,因为子类构造器不恐怕显式或隐式地调用该类(父类)的私有构造器。

概念私有构造器
public class ToolClass {
    //Supperss default constructor for noninstantiability
    private ToolClass() {
        throw new AssertionError();
    }
}
  • 添加了throw new AssertionError()幸免了实例化ToolClass类;
  • 私家了无参构造器,那样顾客端从未艺术调用默许构造函数来实例化该类;也制止了继续的子类实例化的标题。

实例化如下类会报如下所示错误:

public class ToolClass {

    //Supperss default constructor for noninstantiability
    private ToolClass() {
        throw new AssertionError();
    }

    public static void main(String[] args) {
        ToolClass toolClass = new ToolClass();
    }
}

上述代码推行会报如下错误:

Exception in thread "main" java.lang.AssertionError
    at g.ToolClass.<init>(ToolClass.java:9)
    at g.ToolClass.main(ToolClass.java:13)

注:throw new AssertionError()不是少不了的,不过它能够制止十分大心在类的里边调用构造器。

在图谋继续ToolClass时会报以下错误:

Implicit super constructor ToolClass() is not visible for default constructor. 
        Must define an explicit constructor

2. 使用办法

单纯将构造器修饰为私有是相当不足的,大家还索要在构造器中抛出极度手艺到达确实不可实例化的功能,代码如下:

public class MyObject{
        private MyObject(){
            throw new AssertionError("MyObject cant not have instance");
        }
}

图片 1AssertionError可避防止相当的大心在类的里边调用构造函数。它能够确定保障此类在另外意况下都不会被实例化。这种习贯功效有一点点违背直觉,好像构造函数是刻意安顿成不可能被调用同样。由此,明智的做法是在代码中追加一条注释。

 

3. 缺点

这种做法也可能有和好的欠缺,这就是无法再被一而再了

package com.effect.java.chapter02.item04;

/**
 * 私有构造器防止new
 * @author 15620646321@163.com
 * @date 2017年3月14日
 */
public class TestUtil {

    //工具类防止实例化
    private TestUtil() {
        throw new AssertionError();
    }
}

使工具类无法被子类化。

  参照他事他说加以考察资料

若风野趣,款待来到场群,【Java初学者学习调换群】:458430385,此群有Java开辟职员、UI设计人士和前端程序猿。有问必答,共同切磋学习,一同发展!
招待关怀本人的微信大伙儿号【Java码农社区】,会定期推送各样干货:

  《Effective
Java 粤语版 第2版》 第4条:通过个人构造器强化不可实例化的力量
P16  

图片 2

qrcode_for_gh_577b64e73701_258.jpg

发表评论

电子邮件地址不会被公开。 必填项已用*标注