Можно ли упростить выдачу ошибок для комбинированного оператора IF?
Так скажи, у меня есть if
утверждение как if (bool1 && bool2) {}
,
Я хочу отображать различные сообщения об ошибках в зависимости от того, какой из этих логических значений не удалось. Обычно я бы сделал что-то вроде:
if (bool1) {
if (bool2) {
// do something
} else {
// throw error for bool2 failing
}
} else {
// throw error for bool1 failing
}
Теперь я точно знаю, что bool1
не удалось, но bool2
может быть и плохим. Поэтому я бы использовал что-то вроде:
if (bool1 && bool2) {
// do something
} else {
if (!bool1) {
// throw error for bool1 failing
}
if (!bool2) {
// throw error for bool2 failing
}
...
}
Однако, это может быть очень длинным, если нужно проверить много переменных, и особенно если вы хотите отображать разные ошибки, если несколько переменных терпят неудачу.
// continuing on the dots of the above code block
if (!bool1 && !bool2) {
// throw error for both failing
}
Есть ли более эффективный метод для этого?
Изменить: Поскольку все данные ответы являются жизнеспособными, а что лучше, субъективно, я не собираюсь принимать любой как "ответ". Не забудьте выбрать метод / ответ, который лучше всего подходит для ваших собственных нужд.
Спасибо всем за ваши предложения.
9 ответов
Лучший способ, которым я могу придумать, это не вкладывать if
заявления. Вместо этого я бы проверял каждое состояние ошибки независимо и накапливал сообщения об ошибках в StringBuilder
:
StringBuilder errorMsg = new StringBuilder();
if (!bool1) {
errorMsg.append("bool1 condition failed\n");
}
if (!bool2) {
errorMsg.append("bool2 condition failed\n");
}
if (!bool3) {
errorMsg.append("bool3 condition failed\n");
}
// etc
if (errorMsg.length() > 0) {
throw new SomeException(errorMsg.toString());
}
// safely execute your code here
Проверьте полезное StringBuilder
класс документов для дальнейшего использования.
Мне не ясно, каков ваш сценарий, но, возможно, я бы подошел к вашей проблеме следующим образом (аналогично ответу DAB):
List<String> errors = new ArrayList<String>();
if(!bool1){
errors.add("Error message 1");
}
if (!bool2) {
errors.add("Error message 2");
}
// other errors
if(!errors.isEmpty()){
throw new Exception(buildErrorsMessage(errors));
}
Нет, я не знаю, как это сделать. Способ сделать это более эффективно - это реструктурировать ваш код, так что вам не нужно слишком глубоко вкладывать if-предложения.
Вы могли бы сделать что-то вроде этого:
public static <T extends Throwable> void throwIf(boolean condition, Supplier<T> e) throws T {
if(condition) throw e.get();
}
throwIf(!bool1 && !bool2, () -> new Exception("big oops"));
throwIf(!bool1, MyException::new);
throwIf(!bool2, () -> new Exception("oops"));
throwIf(!bool3, Error::new);
// do something
Я бы сделал это так
String error=null;
if(!bool)
error="Something";
else if(!bool2)
error="Other message";
else if(!bool3)
error="failed??";
// ...
if(error!=null) {
throw new Exception(error);
}
Если вам нужно выдавать различные типы исключений, вы можете иметь ошибку типа Exception вместо строки, а затем создать исключение в if(! Bool1)
Если у вас много логических значений, которые должны быть в одном состоянии, вы можете выбросить их в массив и посмотреть, содержит ли массив противоположное состояние. Вы можете использовать карту, если вам нужно отслеживать имена переменных для сообщения об ошибке. При создании сообщения об ошибке вы можете зациклить карту и проверить каждое значение.
package com.idfbins.questions;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class maptest {
public static void main(String[] args) {
Map<String, Boolean> maparini = new HashMap<String, Boolean>();
maparini.put("variable1", true);
maparini.put("variable2", true);
maparini.put("variable3", true);
maparini.put("variable4", true);
maparini.put("variable5", true);
System.out.println("All are true? " + allAreTrue(maparini));
System.out.println("All are false? " + allAreFalse(maparini));
System.out.println("Errors for all true: ");
errorsForTrue(maparini);
System.out.println("Errors for all false: ");
errorsForFalse(maparini);
}
public static boolean allAreTrue(Map<String, Boolean> maparini){
return !maparini.containsValue(false);
}
public static boolean allAreFalse(Map<String, Boolean> maparini){
return !maparini.containsValue(true);
}
public static void errorsForFalse(Map<String, Boolean> maparini){
for(Entry<String, Boolean> mapariniEntry : maparini.entrySet()){
if(mapariniEntry.getValue()){
System.out.println(mapariniEntry.getKey() + " was true!");
//You can construct a string to throw in an exception here
}
}
}
public static void errorsForTrue(Map<String, Boolean> maparini){
for(Entry<String, Boolean> mapariniEntry : maparini.entrySet()){
if(!mapariniEntry.getValue()){
System.out.println(mapariniEntry.getKey() + " was false!");
//You can construct a string to throw in an exception here
}
}
}
}
Что вы не измените свой, если?
if(!bool1)
{
if(!bool2)
{
error both
}
error bool1
}
else if(!bool2)
{
error 2
}
else
do somthing
Вот как я обычно это делаю...
String error=null;
if( a )
{
error="Error a";
}
else if( b )
{
error="Error b";
}
else if( c )
{
error="Error c";
}
if( error!=null )
{
throw new Exception(error);
}
if (!bool1 && !bool2) {
// throw error for bool1 && bool2 failing
} else if (!bool1) {
// throw error for bool1 failing
} else {
// throw error for bool2 failing
}