单身模式

t0m*_*cat 6 java singleton

像我之前的问题一样,这个问题引用了Effective Java.这次我有很多子问题.

  1. 特权客户端可以借助该AccessibleObject.setAccessible()方法反射性地调用私有构造函数.如果您需要防范此操作,请修改构造函数.
    究竟如何调用私有构造函数?什么是AccessibleObject.setAccessible()

  2. 您的专家对单身人士采用什么方法?

    // Approach A
    public class Test{
        public static final Test TestInstance = new Test();
        private Test(){ ... }
        .
        .
        .
    }
    
    
    // Approach B
    public class Test{
        private static final Test TestInstance = new Test();
        private Test(){ ... }
        public static Test getInstance() { return TestInstance; }
        .
        .
        .
    }
    
    Run Code Online (Sandbox Code Playgroud)

    第二种方法是不是更灵活,以防我们每次都要检查新实例或每次检查同一个实例?

  3. 如果我尝试克隆类/对象怎么办?

  4. 单元素枚举类型是实现单例的最佳方式.
    为什么?怎么样?

Mar*_*ers 11

特权限制的cleint可以借助AccessibleObject.setAccessible方法反射性地调用私有构造函数.如果需要保护它,请修改构造函数.我的问题是:如何调用私有构造函数?什么是AccessibleObject.setAccessible?

显然,类本身可以调用私有构造函数(例如,从静态工厂方法).反过来说,布洛赫正在谈论的是:

import java.lang.reflect.Constructor;

public class PrivateInvoker {
    public static void main(String[] args) throws Exception{
        //compile error 
//      Private p = new Private();

        //works fine
        Constructor<?> con = Private.class.getDeclaredConstructors()[0];
        con.setAccessible(true);
        Private p = (Private) con.newInstance();
    } 
}

class Private {
    private Private() {
        System.out.println("Hello!");
    } 
}
Run Code Online (Sandbox Code Playgroud)

2.专家对单身人士采取什么方法:

...

通常,第一个是受欢迎的.第二个(假设您TestInstance在返回新实例之前测试if是否为null)以需要同步或线程不安全为代价获得延迟加载.

当你的第二个例子没有TestInstance在声明中分配实例时,我写了上面的内容.如上所述,上述考虑无关紧要.

第二种方法是不是更灵活,以防我们每次都要检查新实例或每次都是同一个实例?

这不是关于灵活性,而是关于何时产生创建一个(且唯一的)实例的成本.如果你选择a)它是在课堂加载时产生的.这通常很好,因为只有在需要时才会加载类.

当你的第二个例子没有TestInstance在声明中分配实例时,我写了上面的内容.如前所述,在两种情况下,Singleton都将在类加载时创建.

如果我尝试克隆类/对象怎么办?

单身人士不应该出于明显的原因而允许克隆.应抛出CloneNotSupportedException,除非由于某种原因实现,否则将自动抛出Cloneable.

单元素枚举类型是实现单例的最佳方式.为什么?如何?

这方面的例子在书中,正如理由一样.你不懂什么部分?