2015-07-20 119 views
1

我敢肯定这是一个非常愚蠢的问题,但我仍然想知道,是否可以动态地强制使用全局变量cause,换句话说,不使用instanceof运算符?Java铸造(动态)

的原因的问题是,我觉得instanceof运营商没有做任何事情大在这里,它只是铸造cause静态,但在任何情况下,它是创造一个new IOException(cause)

因为causeObject类型,我不得不打字输入StringThrowable

private Object cause; // global variable 
//... 
if (failed) 
    throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause); 

下面是实际的代码片段,其中两个重写的方法将被异步调用。

public class Command implements ResponseListener { 
    private Object cause; 

    // ... 
    @Override 
    public void messageReceived(String message, String status) { 
     // ... 
     if (!status.equals(MyConstants.COMPLD_MSG)) { 
      this.cause = status + " received for " + command.split(":")[0] + message; 
      this.failed = true; 
     } 
     doNotify(); 
    } 

    @Override 
    public void exceptionCaught(Throwable cause) { 
     this.cause = cause; 
     this.failed = true; 
     doNotify(); 
    } 

    public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException { 
     // ... 
     if (failed) 
      throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause); 
    } 
} 
+2

的instanceof是definetelly不是铸造。目前还不清楚你的问题是什么,看起来像XY问题。请尝试更具体。万一你在想什么XY问题是:http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – zubergu

+0

我想你可以使用一些阅读方法重载。这段代码实际上有点合理,因为不同的构造函数会根据'cause'的类型被调用。 –

+1

“因为原因是Object类型”。它是或**需要**是?你需要首先做出区分吗? – zubergu

回答

0

为什么不总是一个Throwable为您的原因变量? Throwable似乎更适合表示失败比字符串。此外,它避免了您使用“丑陋”的运营商instanceof

public class Command implements ResponseListener { 
    private Throwable cause; 

    // ... 
    @Override 
    public void messageReceived(String message, String status) { 
     // ... 
     if (!status.equals(MyConstants.COMPLD_MSG)) { 
      this.cause = new Throwable(status + " received for " + command.split(":")[0] + message); 
      this.failed = true; 
     } 
     doNotify(); 
    } 

    @Override 
    public void exceptionCaught(Throwable cause) { 
     this.cause = cause; 
     this.failed = true; 
     doNotify(); 
    } 

    public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException { 
     // ... 
     if (failed) 
      throw new IOException(cause); 
    } 
} 

更新下面的讨论后:

public class Command implements ResponseListener { 
    private String cause; 

    // ... 
    @Override 
    public void messageReceived(String message, String status) { 
     // ... 
     if (!status.equals(MyConstants.COMPLD_MSG)) { 
      this.cause = status + " received for " + command.split(":")[0] + message; 
      this.failed = true; 
     } 
     doNotify(); 
    } 

    @Override 
    public void exceptionCaught(Throwable cause) { 
     if(cause.getMessage().isEmpty()) { 
      this.cause = cause.toString(); 
     } 
     else { 
      this.cause = cause.getMessage(); 
     } 
     this.failed = true; 
     doNotify(); 
    } 

    public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException { 
     // ... 
     if (failed) 
      throw new IOException(cause); 
    } 
} 
+0

非常感谢@Spotted。这是我以前的设计,虽然没有使用新的Throwable(...),但我使用了新的IOException(...),但由于最后一行,我感觉它是错误的,因为它正在打印堆栈跟踪它打印IOException引起:IOException – surz

+0

@surz你是对的。那么简单地抛出_cause_呢? '如果(失败)投掷原因;' – Spotted

+0

现在这是一个很好的问题。这段代码位于中间层,我限制任何第三方异常传播到UI层。在某些情况下,这些第三方异常不包含任何消息,在这种情况下,包装为IOException会产生一个** **由于:**字符串 – surz

0

由于存在的StringThrowable没有共同的父类,这将是作为参数传递给IOException接受,你必须将它转换为一个或另一个,并以此来确定哪些丢给,你有使用instanceof