我确定这是一个非常愚蠢的问题,但是我仍然想知道,是否可以动态地强制转换全局变量cause,换句话说,无需使用instanceof运算符?

这个问题的原因是,我觉得instanceof运算符在这里没有做任何大的事情,它只是静态地投射cause,但是无论哪种情况,它都在创建new IOException(cause)

因为cause的类型为Object,所以我必须将其类型强制转换为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);
    }
}

最佳答案

为什么不总是将Throwable作为您的原因变量? Throwable似乎比String更适合表示失败。另外,它避免了您使用“丑陋的”运算符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);
    }
}

10-06 08:54