2015-07-20 177 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