Java try-catch vs instanceof

时间:2017-04-06 07:48:14

标签: java

我写了一个错误句柄,如下所示。

类型#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。在这个例子中,我需要处理泛型异常类型以及特定的异常类型,因此出现了处理问题。

3 个答案:

答案 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课程中给出的人(我不确定它是否已经包含了可以解决你案件的事情)。