[改善Java代码]异常只为异常服务

异常原本是正常逻辑的补充,但是有时候会被当做主逻辑使用.看如下代码:

 1 public class Client {
 2     enum Color {
 3         Red, Blue;
 4     }
 5 
 6     public static void main(String[] args) {
 7         System.out.println(Contain(Color.class, "Red"));//true
 8         System.out.println(Contain(Color.class, "Yellow"));//false
 9     }
10 
11     // 判断一个枚举是否包含String枚举项
12     public static <T extends Enum<T>> boolean Contain(Class<T> c, String name) {
13         boolean result = false;
14         try {
15             Enum.valueOf(c, name);
16             result = true;
17         } catch (RuntimeException e) {
18             // 只要是抛出异常,则认为是不包含
19         }
20         return result;
21     }
22 }

 判断一个枚举是否包含指定的枚举项,这里会根据valueOf方法是否抛出异常来进行判断,如果抛出异常(一般是IllegalArgumentException异常),则认为是不包含,若不抛出异常则可以认为包含该枚举项,看上去这段代码很正常,但是其中却有三个错误:

1.异常判断降低了系统性能.

2.降低了代码的可读性,只有详细了解valueOf方法的人才能读懂这样的代码,因为valueOf抛出是一个非受检异常.

3.隐藏了运行期可能产生的错误,catch异常,但没有做任何的处理.

上面的代码是用一段异常实现了一个正常的业务逻辑,这导致代码产生了坏味道,我们要在主逻辑中不使用异常.

代码如下:

public class Client {
    enum Color {
        Red, Blue;
    }

    public static void main(String[] args) {
        System.out.println(Contain(Color.class, "不存在的枚举项"));
        System.out.println(Contain(Color.class, "Blue"));
    }

    // 判断一个枚举是否包含String枚举项
    public static <T extends Enum<T>> boolean Contain(Class<T> c, String name) {
        //遍历枚举项
        for(T t:c.getEnumConstants()){
            //枚举项名称是否相等
            if(t.name().equals(name)){
                return true;
            }
        }
        return false;    
    }
}

异常只能用在非正常的情况下,不能成为正常情况的主逻辑,也就是异常只是主场景中的辅助场景,不能喧宾夺主.

而且异常虽然是描述例外事件的,但能避免尽量避免,例如:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Client {
    public static void main(String[] args) {
        File file = new File("文件.txt");
        try {
            FileInputStream fis = new FileInputStream(file);
            /* 其他业务逻辑处理 */
        } catch (FileNotFoundException e) {
            // 异常处理
        }
    }
}

这样一段代码经常在项目中出现,但经常写并不代表不能优化,这里的异常类FileNotFoundException完全可以在它诞生之前就消除掉:先判断文件是否存在,然后再生成FileInputStream对象.

代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Client {
    public static void main(String[] args) {
        File file = new File("文件.txt");
        //经常出现的异常情况,可以先做判断
        if (file.exists() && !file.isDirectory()) {
            try {
                FileInputStream fis = new FileInputStream(file);
                /* 其他业务逻辑处理 */
            } catch (FileNotFoundException e) {
                // 异常处理
            }
        }
    }
}

虽然增加了If判断,增加了代码量,诞生却会减少FileNotFoundException异常出现的几率,提高了程序的性能和稳定性. 

原文地址:https://www.cnblogs.com/DreamDrive/p/5623097.html