You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获Java中setSoTimeout()触发的SocketTimeoutException

问题1:如何捕获特定的SocketTimeoutException

ExecutorService提交Callable任务后,任务内部抛出的所有异常都会被自动包装到ExecutionException中,你通过Future.get()捕获到的永远是外层的ExecutionException,真实的业务异常存放在它的cause属性中,按以下方式处理即可:

try {
    Future<String> connectionFuture = executorService.submit(waitForConnectionCallable);
    String connectionResult = connectionFuture.get();
} catch (InterruptedException e) {
    // 处理线程中断逻辑
    Logs.error(TAG, "等待连接任务被中断");
    e.printStackTrace();
} catch (ExecutionException e) {
    // 取出真实的业务异常
    Throwable cause = e.getCause();
    if (cause instanceof SocketTimeoutException) {
        // 单独处理连接超时逻辑
        Logs.error(TAG, "连接等待超时,未收到客户端连接");
        // 可在此处添加重试、资源释放等自定义逻辑
    } else if (cause instanceof IOException) {
        // 处理其他IO异常
        Logs.error(TAG, "IO异常,建立连接失败");
        cause.printStackTrace();
    } else {
        // 处理其他未知异常
        Logs.error(TAG, "建立连接时发生未知错误");
        cause.printStackTrace();
    }
}

另外你不需要在Callable的call()方法中单独声明抛出SocketTimeoutException,因为SocketTimeoutException本身就是IOException的子类,你已经声明的throws IOException已经完全覆盖了该异常。

问题2:为什么SocketTimeoutException没出现在setSoTimeout()的throws列表

你误解了文档描述的异常抛出主体:

  • setSoTimeout()本身的作用仅为设置Socket的超时参数,不会触发超时逻辑,所以它只会抛出参数非法、底层Socket错误类的异常,也就是文档标注的IllegalArgumentException和SocketException。
  • 文档中提到的SocketTimeoutException,是后续调用accept()阻塞方法时才会抛出的异常,查看ServerSocket.accept()的方法签名就能看到它明确声明了抛出IOException,SocketTimeoutException属于IO异常的子类,完全符合签名要求。

内容的提问来源于stack exchange,提问作者Mahm00d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:09:02