Java 具有实例的类枚举结构?
我使用以下枚举类型:Java 具有实例的类枚举结构?,java,enums,Java,Enums,我使用以下枚举类型: enum Status {OK,TIMEOUT,EXCEPTION} 但现在我想存储异常的确切内容。很遗憾,您无法实例化枚举类型。什么是最好的方式使类似以下的事情成为可能 switch(status) { case(OK) {System.out.println("Everything OK!");break;} case(TIMEOUT) {System.out.println("Timeout :-(");break;} case(EXCEPT
enum Status {OK,TIMEOUT,EXCEPTION}
但现在我想存储异常的确切内容。很遗憾,您无法实例化枚举类型。什么是最好的方式使类似以下的事情成为可能
switch(status)
{
case(OK) {System.out.println("Everything OK!");break;}
case(TIMEOUT) {System.out.println("Timeout :-(");break;}
case(EXCEPTION) {System.out.println("We have an exception: "+status.exception);break;}
}
我的想法
class Status
{
final Exception e;
public final Status OK = new Status(null);
public final Status TIMEOUT = new Status(null);
public Status(Exception e) {this.e=e;}
}
if(status==Status.OK) {System.out.println("Everything OK!");}
else if(status==Status.TIMEOUT) {System.out.println("Timeout :-(");}
else {System.out.println("We have an exception: "+status.exception);}
二,。几类
class Status {}
class StatusOK extends Status {}
class StatusTimeout extends Status {}
class StatusException extends Status
{
final Exception e;
public StatusException(Exception e) {this.e=e;}
}
然后我需要一堆“instanceOf”语句
p.S.:好吧,看来我解释得不够清楚。在我的程序中,我回答请求并存储这些请求的处理状态:
Map<Request,Status> request2Status;
除非一切正常,否则我会使用异常 像 当异常被设计用来做这类事情时,我认为没有必要使用
enum
在您和原始异常之间的层的顶部添加另一层,您可以执行此操作
interface Status {
String getMessage();
}
enum Statuses implements Status {
OK("Everything OK"), TIMEOUT("Timeout :-(");
private final String message;
private Statuses(String message) { this.message = message; }
String getMessage() { return message; }
}
class ExceptionStatus implement Status {
private final String message;
String getMessage() { return "Exception: " + message; }
}
// to print the message
System.out.println(status.getMessage());
除非一切正常,否则我会使用异常 像 当异常被设计用来做这类事情时,我认为没有必要使用
enum
在您和原始异常之间的层的顶部添加另一层,您可以执行此操作
interface Status {
String getMessage();
}
enum Statuses implements Status {
OK("Everything OK"), TIMEOUT("Timeout :-(");
private final String message;
private Statuses(String message) { this.message = message; }
String getMessage() { return message; }
}
class ExceptionStatus implement Status {
private final String message;
String getMessage() { return "Exception: " + message; }
}
// to print the message
System.out.println(status.getMessage());
有几种方法可以实现这一点,但所有这些方法都取决于您不使用枚举或不专门使用枚举。请记住,枚举基本上是一个只有定义良好的单例作为值的类 一种可能的重构方法是使用具有定义良好的单例的普通类,而不是枚举:
class Status implements Serializable {
// for serialization
private enum InternalStatus {
OK, TIMEOUT, EXCEPTION
}
public static final Status OK = new Status(null, InternalStatus.OK);
public static final Status TIMEOUT = new Status(null, InternalStatus.TIMEOUT);
private final Exception exception;
private final InternalStatus internalStatus;
private Status(Exception exception, InternalStatus internalStatus) {
this.exception = exception;
this.internalStatus = internalStatus;
}
public Exception getException() {
return exception;
}
public static Status exceptionStatus(Exception cause) {
if (cause == null) throw new NullPointerException();
return new Status(cause, InternalStatus.EXCEPTION);
}
// deserialization logic handling OK and TIMEOUT being singletons
private final Object readResolve() {
switch (internalStatus) {
case InternalStatus.OK:
return OK;
case InternalStatus.TIMEOUT:
return TIMEOUT;
default:
return this;
}
}
}
您现在可以检查status==status.OK
和status==status.TIMEOUT
。如果您的状态变量既不是OK也不是TIMEOUT,那么它一定是由异常引起的,您可以通过getException
检索异常
另一个缺点是,您失去了
开关
功能,必须通过if
进行检查。有几种方法可以做到这一点,但所有这些方法都取决于您不使用枚举或不专门使用枚举。请记住,枚举基本上是一个只有定义良好的单例作为值的类
一种可能的重构方法是使用具有定义良好的单例的普通类,而不是枚举:
class Status implements Serializable {
// for serialization
private enum InternalStatus {
OK, TIMEOUT, EXCEPTION
}
public static final Status OK = new Status(null, InternalStatus.OK);
public static final Status TIMEOUT = new Status(null, InternalStatus.TIMEOUT);
private final Exception exception;
private final InternalStatus internalStatus;
private Status(Exception exception, InternalStatus internalStatus) {
this.exception = exception;
this.internalStatus = internalStatus;
}
public Exception getException() {
return exception;
}
public static Status exceptionStatus(Exception cause) {
if (cause == null) throw new NullPointerException();
return new Status(cause, InternalStatus.EXCEPTION);
}
// deserialization logic handling OK and TIMEOUT being singletons
private final Object readResolve() {
switch (internalStatus) {
case InternalStatus.OK:
return OK;
case InternalStatus.TIMEOUT:
return TIMEOUT;
default:
return this;
}
}
}
您现在可以检查status==status.OK
和status==status.TIMEOUT
。如果您的状态变量既不是OK也不是TIMEOUT,那么它一定是由异常引起的,您可以通过getException
检索异常
缺点是,您失去了
开关
功能,必须通过进行检查,如果
您应该使正常
和超时
最终
。谢谢!如果没有解决方案可以使用交换机功能,那么这就解决了我的问题!我唯一不喜欢的是最后一个领域的获得者(在我眼里可能只是公开的),但我想这是个人品味的问题。无论如何,转换是邪恶的。如果只需要打印消息,可以在构造对象时将消息分配给字段。新问题:反序列化后,静态字段不再保持相等。因此,我的if(status==status.OK)
在序列化对象并在以后反序列化后不起作用。@kirdie如果需要序列化,则需要自定义序列化逻辑。最简单的方法是使用writeReplace
和readResolve
为OK和TIMEOUT写入特殊对象,并在读取后替换它们。您应该使您的OK
和TIMEOUT
成为最终版本。谢谢!如果没有解决方案可以使用交换机功能,那么这就解决了我的问题!我唯一不喜欢的是最后一个领域的获得者(在我眼里可能只是公开的),但我想这是个人品味的问题。无论如何,转换是邪恶的。如果只需要打印消息,可以在构造对象时将消息分配给字段。新问题:反序列化后,静态字段不再保持相等。因此,我的if(status==status.OK)
在序列化对象并在以后反序列化后不起作用。@kirdie如果需要序列化,则需要自定义序列化逻辑。最简单的方法是使用writeReplace
和readResolve
为OK和TIMEOUT编写特殊对象,并在阅读后替换。很抱歉,我似乎没有足够清楚地解释我的问题,我在问题描述中补充说,在当时我不再有例外。在这种情况下,我会说你有一层翻译,这是一个问题,而不是它的帮助。我会删除它,这样您就只需要原始异常,而不是添加一个层来反转您和原始异常之间的层添加的行为;saveToDisk(request2Status)代码>…几天后Map request2Status=loadFromDisk();向用户显示请求状态(请求状态2)代码>抱歉,似乎我没有足够清楚地解释我的问题,我在问题描述中补充说,我在当时不再有例外。在这种情况下,我会说你有一层翻译,这是一个问题,而不是它的帮助。我会删除它,这样您就只需要原始异常,而不是添加一个层来反转您和原始异常之间的层添加的行为;saveToDisk(request2Status)代码>…几天后Map request2Status=loadFromDisk();向用户显示请求状态(请求状态2)代码>我不太确定你是否应该在同一个问题中发布新的评论。如果问题是一个移动的目标,那么很难理解所有的答案。问题仍然和以前一样,只是先前提出的解决方案有一个问题。但是你的副标题是New solution,并且
class Status implements Serializable {
// for serialization
private enum InternalStatus {
OK, TIMEOUT, EXCEPTION
}
public static final Status OK = new Status(null, InternalStatus.OK);
public static final Status TIMEOUT = new Status(null, InternalStatus.TIMEOUT);
private final Exception exception;
private final InternalStatus internalStatus;
private Status(Exception exception, InternalStatus internalStatus) {
this.exception = exception;
this.internalStatus = internalStatus;
}
public Exception getException() {
return exception;
}
public static Status exceptionStatus(Exception cause) {
if (cause == null) throw new NullPointerException();
return new Status(cause, InternalStatus.EXCEPTION);
}
// deserialization logic handling OK and TIMEOUT being singletons
private final Object readResolve() {
switch (internalStatus) {
case InternalStatus.OK:
return OK;
case InternalStatus.TIMEOUT:
return TIMEOUT;
default:
return this;
}
}
}