如何使用枚举创建单例 class
How to create a singleton class using enum
我正在尝试在 Java 中创建一个单例 class。 Java5 及以上版本的最佳可用解决方案似乎是使用 enum
。但我不确定如何使用 enum
将我的 class 转换为单例 class。以下是我的简化 class:
public class Employee {
private int id;
private String name;
public Employee() {}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
当我在网上搜索答案时,我发现了以下代码:
public enum EasySingleton{
INSTANCE;
}
但是我的 class 变量和方法在哪里?我不确定如何实施。我知道我们可以为 enum
提供方法,但是我的变量会去哪里呢?非常感谢对此的任何帮助。
P.S.: 请不要争论单例是邪恶的还是反模式的。我只是好奇如何使用 enum
.
创建单例
class 和枚举之间的区别不是很大。我将第一行代码更改为 public enum
而不是 public class
并添加了您的实例名称。
public enum Employee { // changed "class" to "enum"
INSTANCE; // added name of the (single) instance
private int id;
private String name;
Employee() {} // removed "public"
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
请记住,如果您想在一个虚拟机中多次 运行 您的代码,单例、枚举实例、静态事物可能会在以后阻碍您。考虑在您的主 class 中创建一个 Employee
的实例,并将其传递给您的应用程序。
除此之外,枚举还有其他一些特殊功能:
- 你不能
extend
另一个class(只能implements
)
- 一些预定义的方法(如
static values()
和 getName()
)可用
- 构造函数只能是包私有的,或者是私有的
您的 "Employee" class 并不是真正应该是单例的东西,但这里是。
public enum Employee {
INSTANCE;
private int id;
private String name;
private Employee() {} //enum constructor must be private
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
那你可以做
Employee.INSTANCE.setName("Hello World!");
(在其他答案和评论中讨论了单例模式是否适合您的示例使用。我会假装回答具体问题,即使它实际上可能不相关。)
Bloch 的 Effective Java 对此进行了很好的讨论。参见第 17-18 页。我直接抄袭这个参考!
基本上,您可以使用枚举或私有构造函数来实施单例模式。 Bloch 更喜欢前者,尽管这种模式不太常见。
例如:
// Enum singleton
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
功能等同于 public 字段方法,并且无需更多样板即可进行序列化。而且永远只会有一个实例,即使面对棘手的反射或序列化访问也是如此。
我正在尝试在 Java 中创建一个单例 class。 Java5 及以上版本的最佳可用解决方案似乎是使用 enum
。但我不确定如何使用 enum
将我的 class 转换为单例 class。以下是我的简化 class:
public class Employee {
private int id;
private String name;
public Employee() {}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
当我在网上搜索答案时,我发现了以下代码:
public enum EasySingleton{
INSTANCE;
}
但是我的 class 变量和方法在哪里?我不确定如何实施。我知道我们可以为 enum
提供方法,但是我的变量会去哪里呢?非常感谢对此的任何帮助。
P.S.: 请不要争论单例是邪恶的还是反模式的。我只是好奇如何使用 enum
.
class 和枚举之间的区别不是很大。我将第一行代码更改为 public enum
而不是 public class
并添加了您的实例名称。
public enum Employee { // changed "class" to "enum"
INSTANCE; // added name of the (single) instance
private int id;
private String name;
Employee() {} // removed "public"
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
请记住,如果您想在一个虚拟机中多次 运行 您的代码,单例、枚举实例、静态事物可能会在以后阻碍您。考虑在您的主 class 中创建一个 Employee
的实例,并将其传递给您的应用程序。
除此之外,枚举还有其他一些特殊功能:
- 你不能
extend
另一个class(只能implements
) - 一些预定义的方法(如
static values()
和getName()
)可用 - 构造函数只能是包私有的,或者是私有的
您的 "Employee" class 并不是真正应该是单例的东西,但这里是。
public enum Employee {
INSTANCE;
private int id;
private String name;
private Employee() {} //enum constructor must be private
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}
那你可以做
Employee.INSTANCE.setName("Hello World!");
(在其他答案和评论中讨论了单例模式是否适合您的示例使用。我会假装回答具体问题,即使它实际上可能不相关。)
Bloch 的 Effective Java 对此进行了很好的讨论。参见第 17-18 页。我直接抄袭这个参考!
基本上,您可以使用枚举或私有构造函数来实施单例模式。 Bloch 更喜欢前者,尽管这种模式不太常见。
例如:
// Enum singleton
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
功能等同于 public 字段方法,并且无需更多样板即可进行序列化。而且永远只会有一个实例,即使面对棘手的反射或序列化访问也是如此。