目标,定义了一个内部类,然后把这个内部类设置为单例。
1. 构造函数私有化
2. 提供获取单例的方式
3. 考虑并发安全
一 使用非静态内部类
public class OuterClass {
public class InnerClass {
}
}
直接定义单例:
.OuterClass.this' cannot be referenced from a static context
public class OuterClass {
public class InnerClass {
private static InnerClass staticField= new InnerClass();
}
}
这种是直接 new 了内部类。结果报错了。
首先这里定义的是 非静态内部类。非静态内部类,可以看作是 外部类的一个 成员。这里 直接new 非静态内部类,而 并没有new 外部类,就相当于 外部类实例不存在,外部类实例不存在的情况下,他的成员怎么能存在呢? 所以 这里 不能直接 new 非静态内部类,改成如下:
public class OuterClass {
public class InnerClass {
private static InnerClass staticField= new OuterClass().new InnerClass();
}
}
Static declarations in inner classes are not supported at language level '8'
这种写法又报了这种错误。一般来说,这种写法应该没什么问题,只是 目前 java8还不支持,需要升级JDK版本才行。
再换一种写法
public class OuterClass {
private static InnerClass staticField= new OuterClass().new InnerClass();
public class InnerClass {
}
}
将静态变量声明为外部类的变量。
二 使用静态内部类
public class OuterClass {
public static class InnerClass {
private static InnerClass staticField= new InnerClass();
}
}
如果是静态内部类,可以 直接独立的进行 new静态内部类。 静态内部类 可以独立存在,而不依赖外部类的实例。
非静态内部类和静态内部类有什么区别
对于访问权限来说,非静态内部类的权限 大于 静态内部类。
非静态内部类可以 访问 外部类的 所有 成员和方法,包括私有的。可以理解为,非静态内部类的实例中,存在一个 外部类的 this的引用
静态内部类,因为可以独立实例化,在静态内部类中 不存在 外部类的 this引用,所以 静态内部类只能访问外部类的 静态成员。
另外,非静态内部类种,不定义静态成员。不然会报错误,可以定义成外部类的静态成员。如果需要在内部类中定义静态成员,可以考虑将类定义为静态内部类。
三 把单例隐藏到一个 静态内部类的内部
public class Test2 {
private static class Holder{
public static Test2 instance = new Test2();
}
public static Test2 getInstance(){
return Holder.instance;
}
}
Test2的单例 实例 隐藏在Test2的静态内部类中,并且 Test2提供了一个 静态方法用来获取 Test2单例实例。这种方式,不会立即实例化Test2,只有再调用获取实例的方法时才会进行Test2的实例化