使用静态工厂的不可变 class
Immutable class using static factories
我正在学习 Joshua Bloch 的 Effective Java,他在其中解释了实现不可变 class 的不同方法。要防止 subclassing,一种方法是使用 final。更复杂的方法是将构造函数设为私有,从而防止外部访问,并使用静态工厂创建对象。
但是,我不明白这个说法:
public class Complex {
private final double re;
private final double im;
private Complex(double re, double im) {
this.re = re;
this.im = im;
}
public static Complex valueOf(double re, double im) {
return new Complex(re, im);
}
}
它最灵活,因为它允许使用多个 package-private 实现 classes.
我知道在没有 public/protected 构造函数的情况下,外部客户不可能继承 class 它,但不明白 'multiple package private implementation classes' 这个词所表达的意思.
注意:这是 Effective Java 中的第 15 项(最小化可变性)。
class 不能被子class 的唯一方法是 class 被标记为 final
。既然这个class不是final
,那么可以subclassed,像这样:
public class Complex {
private final double re;
private final double im;
private Complex(double re, double im) {
this.re = re;
this.im = im;
}
//methods...
static class SubComplex1 extends Complex {
private SubComplex1(double re, double im, double x) {
super(re, im);
//more elements...
}
//you can define/override methods here
}
public static Complex valueOf(double re, double im, double x) {
return new SubComplex1(re, im, x);
}
}
据我所知,约书亚随后谈到了 EnumSet(但我不记得他提到它的上下文)。
EnumSet
是抽象的,也有静态方法of, noneOf等。
有两个类扩展EnumSet
:JumboEnumSet
和RegularEnumSet
。
你不能直接使用它们,因为它们是包私有的(没有 public
关键字):
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E>
java.util
包只能直接使用它们(如果我们不谈论反射或其他一些技术)。
您只需使用 EnumSet
的静态方法,它 returns 您不应该知道的 EnumSet
的某些子类。
看看noneOf
方法的实现:
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
这是多个包私有实现
我正在学习 Joshua Bloch 的 Effective Java,他在其中解释了实现不可变 class 的不同方法。要防止 subclassing,一种方法是使用 final。更复杂的方法是将构造函数设为私有,从而防止外部访问,并使用静态工厂创建对象。
但是,我不明白这个说法:
public class Complex {
private final double re;
private final double im;
private Complex(double re, double im) {
this.re = re;
this.im = im;
}
public static Complex valueOf(double re, double im) {
return new Complex(re, im);
}
}
它最灵活,因为它允许使用多个 package-private 实现 classes.
我知道在没有 public/protected 构造函数的情况下,外部客户不可能继承 class 它,但不明白 'multiple package private implementation classes' 这个词所表达的意思.
注意:这是 Effective Java 中的第 15 项(最小化可变性)。
class 不能被子class 的唯一方法是 class 被标记为 final
。既然这个class不是final
,那么可以subclassed,像这样:
public class Complex {
private final double re;
private final double im;
private Complex(double re, double im) {
this.re = re;
this.im = im;
}
//methods...
static class SubComplex1 extends Complex {
private SubComplex1(double re, double im, double x) {
super(re, im);
//more elements...
}
//you can define/override methods here
}
public static Complex valueOf(double re, double im, double x) {
return new SubComplex1(re, im, x);
}
}
据我所知,约书亚随后谈到了 EnumSet(但我不记得他提到它的上下文)。
EnumSet
是抽象的,也有静态方法of, noneOf等。
有两个类扩展EnumSet
:JumboEnumSet
和RegularEnumSet
。
你不能直接使用它们,因为它们是包私有的(没有 public
关键字):
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E>
java.util
包只能直接使用它们(如果我们不谈论反射或其他一些技术)。
您只需使用 EnumSet
的静态方法,它 returns 您不应该知道的 EnumSet
的某些子类。
看看noneOf
方法的实现:
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
这是多个包私有实现