我写了一个错误句柄,如下所示。
类型#1
public void receive(Socket sockett){
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(sockett.getInputStream()));
int number = dis.readInt();
File[] files = new File[number];
System.out.println("Number of Files to be received: " +number);
for(int i = 0; i< number;i++) {
long fileLength = dis.readLong();
String fileName = dis.readUTF();
final int progressInt = 100/number * (i+1);
files[i] = new File(
Environment.getExternalStorageDirectory()+"/HotspotDemo",
fileName);
FileOutputStream fos = new FileOutputStream(files[i]);
BufferedOutputStream bos = new BufferedOutputStream(fos);
for(int j = 0; j < fileLength; j++) bos.write(dis.read());
bos.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.setProgress(progressInt);
}
});
}
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
但是,为了更好的清晰度和性能,我考虑改进代码,如下所示
类型#2
try{
// Logic
} catch (SpecificException e){
// Handle error-1
} catch (Exception e){
if(e.getCause() instanceof SpecificException){
// Handle error-1
}
// Handle error-2
}
哪种类型会更好地基于JVM方面?
P.S。在这个例子中,我需要处理泛型异常类型以及特定的异常类型,因此出现了处理问题。
答案 0 :(得分:1)
从性能的角度来看,没有区别。
在Java中,catch
blocks'顺序很重要,您可以捕获所声明异常的子类。这意味着JVM无法真正使用任何地图或索引,并且必须在异常表中进行查找,因此逻辑类似于一系列if (e instanceof XXX)
- 这基本上是您的第二种方式。
可读性方面是基于意见的,所以我不会对此发表评论。
JavaWorld has an article解释了在字节码/ JVM级别的catch期间发生了什么。
答案 1 :(得分:0)
您的第一个和第二个选项不一样,因为即使//Handle error-2
也会调用instanceof SpecificException
逻辑,或者您可能需要添加一个else块来处理此问题,如下所示:
try{
// Logic
} catch (Exception e){
if(e instanceof SpecificException || e.getCause() instanceof SpecificException){
// Handle error-1
} else {//else block for other exceptions?
// Handle error-2
}
}
正如你所提到的,无论如何你必须处理Exception
(但是,一般来说,处理泛型Exception
类型不是一个好习惯),你的第二个选项比调用更好更易读在多个地方// Handle error-1
和//Handle error-2
。
答案 2 :(得分:0)
为了避免重复Handle error-1
代码块(即使它只是一行),我可能会选择#2。
如果您经常使用此模式,我也可能会考虑尝试将其包装在实用方法中,例如,对于那些在番石榴Throwables
课程中给出的人(我不确定它是否已经包含了可以解决你案件的事情)。