Условие "если", результатом которого является ложь, но моя программа проходит через это, если в любом случае ???(правда или ложь) - PullRequest
3 голосов
/ 07 декабря 2010

В моей программе JAVA у меня есть условие "если":

    if(  (!pccoNettNoAff && !transOPCVM && !garantie) 
      && (  (pccoCourant == null) 
         || (  (pccoCourant != null && rBale.getPcco() != null) 
            && (  (pccoCourant.getId() != rBale.getPcco().getId()) 
               || (  pccoCourant.getId() == rBale.getPcco().getId() 
                  && tauxCourant!=null && rBale.getTauxCcf()!=null 
                  && rBale.getPartenaire()==null 
                  && rBale.getTauxCcf()!=tauxCourant
                  )
               )      
            )
         )
      )
   {

Мы можем перевести это в логику следующим образом:

Легенда: T = true и F = False: они являются результатом каждого теста

((T) И ((F) ИЛИ ((T) И ((F) ИЛИ (F)))))

Так что мой окончательный результат, очевидно, неверен (режим отладки Eclipse находит тот же результат) Но моя программа в любом случае проходит через это «если».
У меня действительно нет идей, почему это происходит, может быть, есть какое-то ограничение в условии «если» ??

Если у кого-нибудь есть идеи, пожалуйста, помогите мне:)

С уважением,

Cytemax

Ответы [ 7 ]

12 голосов
/ 07 декабря 2010

Я знаю, почему это происходит - потому что это слишком сложно для встроенного условия .

Рефакторинг этого кода в метод (или, возможно, несколько), посредством чего вы можете поместитьвещи в несколько строк, добавление временных переменных и т. д., и станет намного понятнее, что означает , что означает , и почему он этого не делает.Примерно так:

private boolean shouldBeActedOn(PCCO pccoCourant) {
   if (pccoCourant != null) {
      return true;
   }
   final PCCO balePcco = rBale.getPcco()
   if (balePcco != null) {
       // etc.
   }
   ...
}

// Then later, where your current block is:

  if (shouldBeActedOn(pccoCourant, otherArgs)) {
     ...
  }

Будьте уверены, операторы if Java работают правильно.

8 голосов
/ 07 декабря 2010

Одна идея: не иметь такого смешного числа условий в одном утверждении.

У вас практически нет шансов разобраться, что здесь происходит, без упрощения. Извлеките подвыражения в отдельные локальные переменные, а затем заставьте условие if просто объединить эти локальные переменные.

Таким образом, у вас будет намного лучший шанс понять, что происходит. Скорее всего, вы где-то неверно истолковали отладчик ...

6 голосов
/ 07 декабря 2010

Если .getId() возвращает строку, == и != могут работать не так, как вы думаете - он проверит, являются ли они одинаковыми экземплярами, а не равными ли они строками. Посмотрите на String.equals ().

1 голос
/ 07 декабря 2010

Не прямой ответ на ваш вопрос, но я повторю то, что сказали другие. Прежде всего, упростите вашу условную логику; возможно уменьшить с помощью логических правил algreba (если ветвление слишком сложное).

Напоминает мне карты Карно в школе.

Мне нравится определять локальные переменные для каждого отдельного, меньшего условия, чтобы я мог объединить их по существу в один оператор If. Каждое логическое значение может вызвать отдельную функцию для улучшения читаемости.

boolean isTrainingDue( int numDaysLeft ) {

  boolean trainingDue = false;
  boolean isNewUser = (userService.daysSinceSignUp() < 30);
  boolean gracePeriodExpired = (userService.daysLeft() < 1);
  boolean notCertified = 
        !ObjectUtils.isEmpty(p.getExpiredDate()) && 
         ObjectUtils.isEmpty(p.getCertifiedDate());  

  if (isNewUser && notCertified && gracePeriodExpired)
    trainingDue = (numDaysLeft <= 30);

  return trainingDue;       
}
0 голосов
/ 08 декабря 2010

Tks для всех ваших ответов

Я просто преобразую свое состояние в несколько, если и оно, кажется, отлично работает;)

Так что да, мое первое условие было слишком сложным для одной строки "если"условие ^^

снова Tks

Я должен использовать это (rBale.getTauxCcf (). compareTo (tauxCourant))! = 0 вместо rBale.getTauxCcf ()! = tauxCourant.Они оба типа Double, а не double. Я думаю, что это распространенная ошибка, поэтому я хочу поставить меня на путь Райт.

С уважением,

Cytemax

0 голосов
/ 07 декабря 2010

Я согласен с постами других, но кроме этого вы просто не структурировали логику в удобном для чтения виде.Вот моя попытка понять смысл этого длинного предиката:

if(
    !pccoNettNoAff
    && !transOPCVM
    && !garantie
    && (
        pccoCourant == null
        ||
        pccoCourant != null
        && rBale.getPcco() != null
        && (
            pccoCourant.getId() != rBale.getPcco().getId()
            ||
            pccoCourant.getId() == rBale.getPcco().getId()
            && tauxCourant!=null
            && rBale.getTauxCcf()!=null
            && rBale.getPartenaire()==null
            && rBale.getTauxCcf()!=tauxCourant
        )      
    )
)
0 голосов
/ 07 декабря 2010

ОБНОВЛЕНО

ОК, я ошибся в этом вопросе - пропустил несколько скобок ...

Во всяком случае, я думаю, что Берт F на что-то ...

Вы проверяете, не являются ли вещи (pccoCourant и rBale.getTauxCcf ()) пустыми, подразумевая, что они являются ссылками на объекты.

Затем вы проверяете, совпадают ли они (используя ==).

Вы, вероятно, хотите проверить, равны ли они:

 if( 
(!pccoNettNoAff && !transOPCVM && !garantie) 
&& ( 
    (pccoCourant == null) 
        || ( 
            (pccoCourant != null && rBale.getPcco() != null) 
            && ( 
                (pccoCourant.getId() != rBale.getPcco().getId()) 
                || (
                    pccoCourant.getId() == rBale.getPcco().getId() 
                    && tauxCourant!=null && rBale.getTauxCcf()!=null 
                    && rBale.getPartenaire()==null 
                    && ! rBale.getTauxCcf().equals(tauxCourant)
                )
            )      
    )
)
 ){

Остальное можно игнорировать:

Помимо сложности, упомянутой другими, у вас есть некоторая неопределенность в ваших более поздних условиях:

 if( 
(!pccoNettNoAff && !transOPCVM && !garantie) 
&& ( 
    (pccoCourant == null) 
        || ( 
            (pccoCourant != null && rBale.getPcco() != null) 
            && ( 
                (pccoCourant.getId() != rBale.getPcco().getId()) 
                || (pccoCourant.getId() == rBale.getPcco().getId() 
                && tauxCourant!=null && rBale.getTauxCcf()!=null 
                && rBale.getPartenaire()==null 
                && rBale.getTauxCcf()!=tauxCourant)
            )      
    )
    )
 ){

Внутренние вложенные условия объединяют ИЛИ с ANDS на одном уровне. Я подозреваю, что вы хотите:

 if( 
(!pccoNettNoAff && !transOPCVM && !garantie) 
&& ( 
    (pccoCourant == null) 
        || ( 
            (pccoCourant != null && rBale.getPcco() != null) 
            && ( 
                (pccoCourant.getId() != rBale.getPcco().getId()) 
                || (
                    (pccoCourant.getId() == rBale.getPcco().getId() 
                    && tauxCourant!=null && rBale.getTauxCcf()!=null 
                    && rBale.getPartenaire()==null 
                    && rBale.getTauxCcf()!=tauxCourant)
                )
            )      
    )
)
 ){
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...