我使用以下枚举类型:
enum Status {OK,TIMEOUT,EXCEPTION}
但现在我想存储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);}
2。几个类
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”-statements。
P.S。:好吧好像我没有说清楚。在我的程序中,我回答请求,并存储处理这些请求的状态:
Map<Request,Status> request2Status;
因此我不能使用Status.getMessage(exception)之类的东西;因为在我的代码中的那个位置我不知道它是哪个例外。这就是为什么我要将保存在状态。
选择解决方案
private static class LearnStatus implements Serializable
{
private static final long serialVersionUID = 1L;
public static final LearnStatus OK = new LearnStatus(null);
public static final LearnStatus TIMEOUT = new LearnStatus(null);
public static final LearnStatus NO_TEMPLATE_FOUND = new LearnStatus(null);
public static final LearnStatus QUERY_RESULT_EMPTY = new LearnStatus(null);
public static final LearnStatus NO_QUERY_LEARNED = new LearnStatus(null);
public final Exception exception;
private LearnStatus(Exception exception) {this.exception = exception; }
public static LearnStatus exceptionStatus(Exception cause)
{
if (cause == null) throw new NullPointerException();
return new LearnStatus(cause);
}
@Override public String toString()
{
if(this==OK) {return "OK";}
if(this==TIMEOUT) {return "timeout";}
if(this==NO_TEMPLATE_FOUND) {return "no template found";}
if(this==QUERY_RESULT_EMPTY) {return "query result empty";}
if(this==NO_QUERY_LEARNED) {return "no query learned";}
return "<summary>Exception: <details>"+exception.getLocalizedMessage()+"</details></summary>";
}
}
有问题
如果我序列化了包含Status.OK
的对象,则在反序列化后if(status==Status.OK)
不再有效。
新解决方案
我现在在课程中包含了一个枚举类型。你觉得怎么样?
private static class LearnStatus implements Serializable
{
public enum Type {OK, TIMEOUT, NO_TEMPLATE_FOUND,QUERY_RESULT_EMPTY,NO_QUERY_LEARNED,EXCEPTION}
public final Type type;
private static final long serialVersionUID = 1L;
public static final LearnStatus OK = new LearnStatus(Type.OK,null);
public static final LearnStatus TIMEOUT = new LearnStatus(Type.TIMEOUT,null);
public static final LearnStatus NO_TEMPLATE_FOUND = new LearnStatus(Type.NO_TEMPLATE_FOUND,null);
public static final LearnStatus QUERY_RESULT_EMPTY = new LearnStatus(Type.QUERY_RESULT_EMPTY,null);
public static final LearnStatus NO_QUERY_LEARNED = new LearnStatus(Type.NO_QUERY_LEARNED,null);
public final Exception exception;
private LearnStatus(Type type, Exception exception) {this.type=type;this.exception = exception;}
public static LearnStatus exceptionStatus(Exception cause)
{
if (cause == null) throw new NullPointerException();
return new LearnStatus(Type.EXCEPTION,cause);
}
@Override public String toString()
{
switch(type)
{
case OK: return "OK";
case TIMEOUT: return "timeout";
case NO_TEMPLATE_FOUND: return "no template found";
case QUERY_RESULT_EMPTY:return "query result empty";
case NO_QUERY_LEARNED: return "no query learned";
case EXCEPTION: return "<summary>Exception: <details>"+exception.getLocalizedMessage()+"</details></summary>";
default: throw new RuntimeException("switch type not handled");
}
}
}
答案 0 :(得分:3)
除非一切正常,否则我会使用Exception。
像
System.out.println("Everything OK!");
} catch(TimeoutException te) {
System.out.println("Timeout :-(")
} catch(Exception e) {
System.out.println("We have an exception: " + e);
}
当Exceptions被设计为执行此类操作时,我认为不需要使用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());
答案 1 :(得分:1)
有几种方法,但所有这些方法都取决于您不使用Enums或不使用它们。请记住,枚举基本上是一个只有明确定义的单例作为值的类。
一种可能的重构是使用具有定义明确的单例而不是枚举的普通类:
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
。如果您的状态变量既不正常也不是TIMEOUT,则必须由异常引起,您可以通过getException
检索该异常。
作为缺点,您将失去switch
功能,必须通过if
进行检查。