![](/img/trans.png)
[英]Joshua Bloch #Item 1: Consider static factory methods instead of constructors
[英]Joshua Bloch Item #1 Static Factory Methods Instead of Constructors - Object creation
我想知道 Joshua Blochs“Effective Java”第 3 版第 1 项中描述的 Static 工厂方法的以下优点:
static 工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时都创建一个新的 object。 这允许不可变类(条目 15)使用预构造的实例,或者在构造实例时缓存实例,并重复分配它们以避免创建不必要的重复对象。 Boolean.valueOf(boolean) 方法说明了这种技术:它从不创建 object。
请参阅此处的摘录。
引起我注意的是关于valueOf(boolean)
没有创建 object 的最后一行。根据这本书
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
public static Boolean valueOf(boolean b)
返回表示指定 boolean 值的 Boolean 实例。 如果指定的 boolean 值为真,则此方法返回 Boolean.TRUE; 如果为假,则此方法返回 Boolean.FALSE。 如果不需要新的 Boolean 实例,通常应优先使用此方法而不是构造函数 Boolean(boolean),因为此方法可能会产生明显更好的空间和时间性能。
因此,根据我的理解和 Javadoc(“返回 Boolean 实例...”),static 方法确实返回 Boolean,因此返回 object - 因为它实际上是返回类型。 在以下情况下:
public class MyClass {
public static void main(String args[]) {
Boolean booleanWrapped = Boolean.valueOf(true);
System.out.println(booleanWrapped);
}
}
booleanWrapped
是我的 object 我可以像在prinln()
语句中一样使用 eg。
那么如果约书亚说我在这里错过了什么
Boolean.valueOf(boolean) [...]永远不会创建 object
我知道一个带有现有答案的类似问题,但它似乎没有完全回答我的问题,因为在我上面的示例中没有“预先存在的”实例。?!
您的 booleanWrapped 变量不引用新创建的 object。它引用 static Boolean.TRUE
第一次创建 Boolean class 负载。 对Boolean.valueOf(true)
的所有调用都简单地重复使用单个 object。
自 Java 9 起,Boolean 已弃用构造函数。 但这仍然表明了差异。
所以Boolean b1 = new Boolean(true).
创建一个新实例并将其存储在b1
中。
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(true);
System.out.println(System.identityHashCode(b1));
System.out.println(System.identityHashCode(b2));
两个不同的身份哈希码表示不同的对象
804564176
1421795058
现在使用现有的 static 实例。
Boolean b1 = Boolean.TRUE;
Boolean b2 = Boolean.TRUE;
System.out.println(System.identityHashCode(b1));
System.out.println(System.identityHashCode(b2));
共享相同的 object - 相同的哈希码。
804564176
804564176
在 Boolean class 中,您有以下内容:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
所以它们是在加载 class 时创建的。
valueOf
方法永远不会创建一个新的 object(没有new
表达式,也没有其他可以传递调用构造函数的方法调用)。 该方法仅返回 2 static 字段之一( Boolean.TRUE
或Boolean.FALSE
)。 这些字段已经存在并且它们引用的对象已经创建(在方法valueOf
之外和之前)。
显然,必须在某处创建对象; 但它们不是在方法valueOf
中创建的。
而“返回一个对象”。=“创建一个对象”。
public static Object demo() {
final Object obj = new Object(); // `new` creates the object
return obj; // `return` returns the object, it does not create a new one
}
Boolean.TRUE
和Boolean.FALSE
都是预先存在的static
成员,由 Boolean class 定义。
在理解 static 工厂方法相对于传统构造函数的优势时,一个不可忽视的重要概念是为什么 Josh Bloch 指定可以缓存或预构造不可变类。 重点不在于在第一次调用static工厂方法时是否构造了一个object,而是在多次使用时如何节省资源。 节省的全部是返回一个预先存在的不可变实例,而不是构建一个新实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.