Java:Why抽象class经常有一个静态方法?这个的目的是什么?
Java:Why the abstract class often has a static method?And the purpose of this?
我经常阅读Java的源代码,但我发现了一个有趣的事情。许多有用的class或封装,例如,如果我想获得this的对象,我可以使用来自抽象class的静态方法而不是new。有没有人告诉我enter image description here that? Thanks a lot.For example, I want to get a ByteBuff.enter image description here
的目的
这种方法称为静态工厂模式。这样做有很多原因,以下是我所知道的一些原因:
更容易read/use
以java.time.Duration
为例,你会注意到这个class也有一个私有构造函数。您还会注意到 Duration.ofDays()
、Duration.ofHours()
等方法。
如果这个 class 是公开它的构造函数(让它成为 public),那么你会期望这样的东西:
public Duration(long days, long hours, long minutes, long seconds, long milliseconds, long nanoseconds)
这样做会很麻烦,因为大多数人不会创建像“1天2小时3分4秒5毫秒6纳秒”这样的持续时间。
抽象实现
这实际上是ByteBuffer
使用这种方法的主要原因。 ByteBuffer
本身其实就是一个abstract
class。有许多实现 classes,但它一直对用户隐藏。 ByteBuffer.allocate()
实际上 return 是 DirectByteBuffer
的一个实例,但您甚至不知道 DirectByteBuffer
甚至存在!这是因为 class 本身是包私有的。
缓存
有些 API 可能会在内部进行某种缓存,以免创建相同内容的过多副本。这些通常出现在不可变的 classes 中,其中的值将保持不变。静态 "creational" 方法允许 class 查找缓存实例 return 给调用者,而不是允许调用者创建它的过多实例。另一个用例是尝试重用重新创建的对象。
部分final
一些 API 可能会尝试实现类似于 final
class 的东西。
package com.test
public class Test {
Test() { // package-private
}
public Test create() { return new Test(); }
}
这允许 API 创建扩展此 Test
class 的新 classes,同时阻止其他人创建 classes Test
。这是因为 com.test
包之外的 subclasses 将无法调用 super()
.
但是,在 Java 9.
中引入模块后,这不再是必需的
我经常阅读Java的源代码,但我发现了一个有趣的事情。许多有用的class或封装,例如,如果我想获得this的对象,我可以使用来自抽象class的静态方法而不是new。有没有人告诉我enter image description here that? Thanks a lot.For example, I want to get a ByteBuff.enter image description here
的目的这种方法称为静态工厂模式。这样做有很多原因,以下是我所知道的一些原因:
更容易read/use
以java.time.Duration
为例,你会注意到这个class也有一个私有构造函数。您还会注意到 Duration.ofDays()
、Duration.ofHours()
等方法。
如果这个 class 是公开它的构造函数(让它成为 public),那么你会期望这样的东西:
public Duration(long days, long hours, long minutes, long seconds, long milliseconds, long nanoseconds)
这样做会很麻烦,因为大多数人不会创建像“1天2小时3分4秒5毫秒6纳秒”这样的持续时间。
抽象实现
这实际上是ByteBuffer
使用这种方法的主要原因。 ByteBuffer
本身其实就是一个abstract
class。有许多实现 classes,但它一直对用户隐藏。 ByteBuffer.allocate()
实际上 return 是 DirectByteBuffer
的一个实例,但您甚至不知道 DirectByteBuffer
甚至存在!这是因为 class 本身是包私有的。
缓存
有些 API 可能会在内部进行某种缓存,以免创建相同内容的过多副本。这些通常出现在不可变的 classes 中,其中的值将保持不变。静态 "creational" 方法允许 class 查找缓存实例 return 给调用者,而不是允许调用者创建它的过多实例。另一个用例是尝试重用重新创建的对象。
部分final
一些 API 可能会尝试实现类似于 final
class 的东西。
package com.test
public class Test {
Test() { // package-private
}
public Test create() { return new Test(); }
}
这允许 API 创建扩展此 Test
class 的新 classes,同时阻止其他人创建 classes Test
。这是因为 com.test
包之外的 subclasses 将无法调用 super()
.
但是,在 Java 9.
中引入模块后,这不再是必需的