Java — универсальный язык программирования, который имеет множество альтернативных решений для ваших конкретных потребностей.
Однако есть хорошие подходы, которым следует следовать, а есть и неудачные подходы, которые мы до сих пор в основном используем.
Одним из наиболее распространенных неудачных подходов является использование исключений для управления потоком выполнения.
Этого следует избегать по двум причинам:
- Это снижает производительность и скорость вашего кода.
- Это делает ваш код менее читаемым
Здесь исключение используется для управления потоком выполнения:
Если пользователь предоставляет значение имени, отличное от NULL, метод findAge вернет длину этого имени, но если имя пользователя имеет значение NULL, метод findUser выдаст исключение NameNotFoundException, и в этом случае метод findAge вернет 0. Как мы можем преобразовать этот код без использования исключений? В общем, вариантов много, рассмотрим один из них:public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if(name==null) { throw new NameNotFoundException(); } return name; }
public static int findAgeNoEx(String name) {
String ageAsString = findUserNoEx(name);
return ageAsString.length();
}
private static String findUserNoEx(String name) {
if(name==null) {
return "";
}
return name;
}
Чтобы выяснить влияние исключения на производительность, я подготовил следующий код, который вызывает оба метода с исключением и без него 10 миллионов раз.
public class ControlFlowWithExceptionOrNot {
public static class NameNotFoundException extends RuntimeException {
private static final long serialVersionUID = 3L;
}
private static final int TRIAL = 10000000;
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
for (int i = 0; i < TRIAL; i++) {
findAgeNoEx(null);
}
System.out.println("Duration :" + (System.currentTimeMillis() - start));
long start2 = System.currentTimeMillis();
for (int i = 0; i < TRIAL; i++) {
findAge(null);
}
System.out.println("Duration :" + (System.currentTimeMillis() - start2));
};
public static int findAge(String name) {
try {
String ageAsString = findUser(name);
return ageAsString.length();
} catch (NameNotFoundException e) {
return 0;
}
}
private static String findUser(String name) {
if (name == null) {
throw new NameNotFoundException();
}
return name;
}
public static int findAgeNoEx(String name) {
String ageAsString = findUserNoEx(name);
return ageAsString.length();
}
private static String findUserNoEx(String name) {
if (name == null) {
return "";
}
return name;
}
}
Заключение: Duration :16
Duration :6212
Как видите, использование исключения стоило нам тысяч миллисекунд на моем Intel Core i7-3630QM.
Если сравнить два наших метода findAge с точки зрения читабельности, то все без исключения методы абсолютно понятны: во-первых, мы можем быть абсолютно уверены, что метод findUser возвращает строку; а во-вторых, независимо от того, какая строка будет возвращена, мы получим ее длину.
При этом метод с исключением несколько сбивает с толку: не совсем понятно, что именно возвращает метод findUser. Он может вернуть строку или выдать исключение, и это не видно из сигнатуры метода.
По этой причине парадигма функционального программирования не рекомендует использовать исключения.
В конце концов, будет лучше, если вы будете использовать исключения там, где исключение действительно возникает и необходимо.
Если вы используете исключения для управления потоком выполнения, это приведет к снижению производительности и сделает ваш код менее читаемым.
Надеюсь, эта статья показалась вам интересной и, возможно, полезной.
Теги: #java #Исключение
-
Как Устранить Ошибку Hotmail
19 Oct, 24 -
Знаменитости И Игры-Одевалки
19 Oct, 24 -
200 — Это Хорошо Или Плохо?
19 Oct, 24 -
Выпущена Qt 4.7.0
19 Oct, 24