当我抓住它时,我需要以不同的方式处理它SocketTimeoutException
。我发现唯一的事情就是依赖getMessage()
. 到目前为止,我发现了两个:
java.net.SocketTimeoutException: connect timed out
java.net.SocketTimeoutException: Read timed out
消息(连接超时、读取超时)是硬编码的吗?它们是在哪里生成的?至少这些消息的任何常数值?
您可以检查 Socket.isConnected。但是由于异常是由不同的方法引发的,所以最好使用两个具有不同操作的 catch 块。
try {
socket.connect(address);
} catch (SocketTimeoutException e) {
throw new SocketConnectionException(e);
}
try {
socket.getInputStream();
...
} catch (SocketTimeoutException e) {
throw new SocketReadException(e);
}
它们来自不同的方法。隐式或显式调用 connect() 时会发生“连接超时”;调用 read() 或其同源之一时会发生“读取超时”。所以你可以区分只有两个不同的 catch 块。但无论哪种情况,您都可能要关闭连接...
所以,这是我声名鹊起的地方。在这里,我们沿着 StackTrace 走,寻找异常的起源方法。
public class ExceptionOriginTracing {
public static void main(String[] args){
try {
originOne();
originTwo();
} catch (Exception e){
// Now for the magic:
for (StackTraceElement element : e.getStackTrace()){
if (element.getMethodName().equals("originOne")){
System.out.println("It's a read error!");
break;
} else if (element.getMethodName().equals("originTwo")){
System.out.println("It's a write error!");
break;
}
}
}
}
public static void originOne() throws Exception{
throw new Exception("Read Failed...", null);
}
public static void originTwo() throws Exception{
throw new Exception("Connect failed...", null);
}
}
解析异常给出的消息的不同之处在于,一个简单的字符串比实际方法的名称更有可能发生变化。
除此之外,这不是最佳解决方案!但遗憾的是,这里没有最佳解决方案。
此外,使用这种方法,在使用源混淆时必须格外小心,这将改变方法名称,从而改变 的返回值getMethodName()
。
设计这样的东西时,正确的方法是将异常包装在一个新的异常中,它提供了通过使用标志或枚举来实际找出真正起源的方法。
解析消息/StackTrace 总是感觉很脏,并且在未来的版本中会被破坏!
回复有点晚。我只有一个布尔标志'isConnected'初始化为false。连接后,我将其设置为true。如果连接超时,您将永远无法到达那里。
在抛出异常后检查 Socket.isConnected 听起来是个坏主意。到那时,套接字可能会被关闭。
通过在 之前定义标志try
,它可以在catch
处理程序中读取。