zoukankan      html  css  js  c++  java
  • Item 4 ----通过私有构造器强化不可实例化的能力

    场景:

    在创建工具类的时候,大部分是无需实例化的,实例化对它们没有意义。在这种情况下,创建的类,要确保它是不可以实例化的。
     
    存在问题:
    在创建不可实例化的类时,虽然没有定义构造器。但是,客户端在使用该类的时候,依然可以实例化它。客户端,可以继承该类,通过实例化其子类来实现实例化;客户端可以调用默认的构造器来实例化该类。
     
    要避免这个问题,使用的方式是,定义一个私有的构造器:
    public class UtilityClass {
        // Suppress default constructor for noninstantiability
        private UtilityClass() {
            throw new AssertionError();
        }
    }
    
    添加 throw new AssertionError(),是避免在UtilityClass实例化UtilityClass类。
    因为有了私有的无参构造器,这样客户端就没有办法调用默认构造器来实例化该类;也避免了继承的子类被实例化的问题。
     
    比如:
    public class UtilityClass {
        // Suppress default constructor for noninstantiability
        private UtilityClass() {
            throw new AssertionError();
        }
    
        public static UtilityClass getInstance()
        {
            return new UtilityClass ();
        }
    }
    
    public class Test {
    
        public static void main(String[] args)
        {
    
            UtilityClass one = UtilityClass .getInstance();
        }
    }
    
    上述代码执行了之后,会报如下错误:
    Exception in thread "main" java.lang.AssertionError
           at org.effectivejava.examples.chapter02.item04.UtilityClass.<init>(UtilityClass.java:8)
           at org.effectivejava.examples.chapter02.item04.UtilityClass.getInstance(UtilityClass.java:13)
           at org.effectivejava.examples.chapter02.item04.Test.main( Test.java:9)
     
    添加throw new AssertionError()可以成功避免在UtilityClass中实例化UtilityClass类。
    可以成功避免如下代码执行:
    public class SubUtilityClass extends UtilityClass {
    
    }
    
    当试图继承该类时,会提示如下错误:
    Implicit super constructor UtilityClass() is not visible for default constructor. Must define an explicit constructorImplicit super constructor UtilityClass() is not visible for default constructor. Must define an explicit constructor
    客户端也无法调用默认的构造器。
    public class Test {
    
        public static void main(String[] args)
        {
    
           // UtilityClass one = new UtilityClass();
        }
    }
    

      

  • 相关阅读:
    过滤的特殊字符
    iOS中正则表达式的基本使用方法
    sqlite3特殊的字符转义
    tableView的设置
    IOS中设置cell的背景view和选中时的背景view 、设置cell最右边的指示器(比如箭头文本标签)
    IOS中(类似于进度条哪种效果)MBProgressHUD的使用
    ISO中AFN的使用步骤
    IOS中用UIFont返回字体的行高、动态改变tableView中Cell的高度
    iso中第三方框架SDWebImage的使用步骤
    iso中自动伸缩属性
  • 原文地址:https://www.cnblogs.com/ttylinux/p/4355779.html
Copyright © 2011-2022 走看看