2014-10-22 5 views
1

У меня есть открытый метод, который вызывает частный метод, который условно вызывает другой частный метод. Все три метода возвращают логическое примитивное значение, однако значение иногда изменяется от того, что я ожидаю.Java: логический примитивный частный метод, возвращающий false, даже если установлен в true

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

Вот очищен версия образец кода и результаты, которые я вижу:

EDIT: Я добавил ФАКТИЧЕСКУЮ код в нижней

public class MyClass { 

    // Default Constructor 
    public MyClass() {} 

    public boolean foo(final Object arg0, final Object arg1, final Object arg2) { 
     final boolean result = this.bar(arg0, arg1, arg2); 
     System.out.println("foo: " + result); 
     return result; 
    } 


    private boolean bar(final Object arg0, final Object arg1, final Object arg2) { 
     boolean result = false; 
     System.out.println("bar: " + result); 

     try { 
      // complicated code that could generate an exception 

      if (this.wowsers(arg0, arg1, arg2)) { 
       result = true; 
       System.out.println("bar: " + result); 
       System.out.println("bar: call to wowsers() returned true"); 
      } 

     } catch (Exception e) { 
      System.out.println("SOMETHING BLEW UP"); 
      e.printStackTrace(); 
     } finally { 
      // This should NOT change result 
      this.irrelevantMethod_1(null); 
      this.irrelevantMethod_2(null); 
      this.irrelevantMethod_3(null); 
     } 

     System.out.println("bar: " + result); 
     return result; 
    } 

    private boolean wowsers(final Object arg0, final Object arg1, final Object arg2) { 
     boolean result = false; 

     // complicated code involving the passed in arguments 
     // this MIGHT change result 

     System.out.println("wowsers: " + result); 
     return result; 
    } 

    private void irrelevantMethod_1(Object arg0) { 
     // Nothing in here to change result 
    } 

    private void irrelevantMethod_2(Object arg0) { 
     // Nothing in here to change result 
    } 

    private void irrelevantMethod_3(Object arg0) { 
     // Nothing in here to change result 
    } 
} // END Class MyClass 

Телефонный код:

MyClass myInstance = new MyClass(); 
myInstance.foo(); 

Консоль вывода:

> bar: false 
> wowsers: true 
> bar: true 
> bar: call to wowsers() returned true 
> foo: false 

В приведенном выше примере значение результата получает значение true в методах dowsers() и корректно возвращается в bar(). Когда bar() проверяет возвращаемое значение от wowsers() и считает его истинным, он устанавливает свой собственный результат в true и выводит на консоль значение результата и выводит, что dowsers() возвратил true.

System.out.println в конце строки bar() НИКОГДА не выполняется (по крайней мере, я никогда не вижу ничего в консоли), а значение результата (которое в этой точке равно true) возвращается как ложный.

Затем метод foo() печатает значение, полученное от вызова в бар, которое всегда является ложным.

Кто-нибудь видит, где я запутался?

EDIT: Вот АКТУАЛЬНО код -replaces методы Foo() и бар()

public boolean sendReminderNotifcation(final RequestController controller, final Session session, final Request request, 
     final Comment comment, final boolean treatAsNewNote) { 

    final boolean result = this.sendNotification(controller, session, request, comment, null, MailType.Remind, treatAsNewNote); 
    System.out.println("sendReminderNotifcation(): " + result); 
    System.out.println("***"); 
    return result; 
} 



private boolean sendNotification(final RequestController controller, final Session session, final Request request, 
     final Comment comment, final TreeSet<String> copyto, final MailType mailtype, final boolean treatAsNewNote) { 

    HashMap<NotifyWhom, TreeSet<String>> sendTo = null; 
    boolean result = false; 

    System.out.println("sendNotification(): " + result); 

    try { 
     if (null == controller) { throw new IllegalArgumentException("RequestContoller is null"); } 

     this.setRequestURLprefix(controller.getRequestURLprefix()); 

     if (null == session) { throw new IllegalArgumentException("Session is null"); } 
     if (null == request) { throw new IllegalArgumentException("Request is null"); } 
     if (null == mailtype) { throw new IllegalArgumentException("mailtype is null"); } 

     final EnumSet<NotifyWhom> recipients = this.getRecipients(controller, session, request, mailtype, treatAsNewNote); 

     if ((null == recipients) || recipients.isEmpty()) { return false; } 

     final HashMap<NotifyWhom, TreeSet<String>> tempSendTo = this.getSendTo(controller, request, recipients); 
     if (null == tempSendTo) { throw new RuntimeException("NO RECIPIENTS FOR NOTIFICATION"); } 

     // clear out any duplicates 
     sendTo = this.purgeDuplicateRecpients(tempSendTo); 

     // Update Prior Assignee Information 
     // Update Requestor Information 
     // Update Queue Owner Information 
     this.updateReOpenedInformation(controller, session, request); 

     final String subject = (request.isReOpened()) ? HelpdeskNotifications.SUBJECT_REOPENED : HelpdeskNotifications.SUBJECT_UPDATED; 

     final Iterator<Entry<NotifyWhom, TreeSet<String>>> sit = sendTo.entrySet().iterator(); 
     final TreeSet<NameHandle> exclude = this.getExcludeRecipients(); 
     while (sit.hasNext()) { 
      final Map.Entry<NotifyWhom, TreeSet<String>> entry = sit.next(); 
      final MailNotifyKey key = new MailNotifyKey(this.getLogger(), mailtype, entry.getKey()); 
      if (MailType.Remind.equals(mailtype)) { 
       final Status status = request.getStatus(); 
       final MailRecipientOption mro = (null == status) ? null : status.getMailRecipientOption(key); 

       // A null mro indicates that Notifications are DISABLED 
       if (null == mro) { return false; } 
      } 

      final TreeSet<String> sendto = entry.getValue(); 
      if (this.sendEmail(controller, session, request, subject, comment, sendto, copyto, exclude, key, treatAsNewNote)) { 
       result = true; 
       System.out.println("sendNotification(): " + result); 
       System.out.println("sendNotification(): (call to sendEmail() returned true)"); 
      } 
     } 

     // Send Special Re-Opened Notifications 
     if (this.sendReOpenedNotifications(controller, session, request, subject, comment, treatAsNewNote)) { 
      result = true; 
      System.out.println("sendNotification(): " + result); 
      System.out.println("sendNotification(): (call to sendReOpenedNotifications() returned true)"); 
     } 

    } catch (final Exception e) { 
     this.getLogger().logException(this, e); 
     e.printStackTrace(); 
    } finally { 
     this.setPriorAssigneeNotify(null); 
     this.setReOpenedRecipients(null); 
     this.setExcludeRecipients(null); 
    } 

    System.out.println("sendNotification(): " + result); 
    return result; 
} 

Консоль Выход я получаю:

> sendNotification(): false 
> sendNotification(): true 
> sendNotification(): (call to sendEmail() returned true) 
> sendReminderNotifcation(): false 
> *** 

(я понимаю, что я должен внесли код ACTUAL в первую очередь)

По какой-то причине я не могу понять, кажется, что последние две строки кода в панели методов() и метод sendNotification() не работают. Есть ли другой способ для завершения и возврата метода, о котором я не знаю?

+0

Третий журнал «bar + result» не включен в ваш вывод на консоль, но нет ничего, что могло бы быть пропущено, так как нет раннего возврата или блока catch, который позволял бы выполнять только журнал «foo» , – njzk2

+0

Да, точно. Это одна из вещей, которые я не могу понять. Он должен появляться, но это не так. Я проверил и проверил и перепроверял, чтобы убедиться, что в этом методе нет другого оператора возврата, и он не может его найти. – spanky762

+0

что-то определенно отсутствует в коде, который вы вставили. – njzk2

ответ

1

Я предлагаю вам положить заявление отладки печати до этой строки:

   if (null == mro) { return false; } 

Поскольку это в цикле while и позволяет методу возвращать false даже th ough result был установлен верно. Я готов поспорить, что это то, откуда приходит ложное возвращение, и почему вы не видите исполняемые окончательные операторы печати.

+0

BINGO. Спасибо за гвозди. – spanky762

0

Прочитайте это:

Is Java "pass-by-reference" or "pass-by-value"?

В этом методе

private boolean wowsers(final Object arg0, final Object arg1, final Object arg2) { 
    boolean result = false; 

    // complicated code involving the passed in arguments 
    // this MIGHT change result 

    System.out.println("wowsers: " + result); 
    return result; 
} 

Вы повторно инстанцирует булево Название переменной. Это новый boolean result вне диапазона метода bar

Просто блок. Просто думай.

  result = true; 
      System.out.println("bar: " + result); 

И, наконец, это выглядит как

private boolean bar(final Object arg0, final Object arg1, final Object arg2) { 
    boolean result = false; 
    // no reassignee result value 
    return result; 
} 

так вы возвращаетесь ложные

+0

Благодарим вас за ответ. Я обновил исходный вопрос, включив в него фактический код. Я не уверен, полностью ли я понимаю ваш ответ в том, что я не передаю значение результата в методы, просто верну его. Объем должен быть локальным и независимым внутри каждого метода, а возвращаемое значение. Пожалуйста, объясните, если я не понимаю здесь. – spanky762

+0

попытайтесь добавить ** синхронизированный ** в оба метода модификаторов. –

0
final boolean result 

Это означает, что вы хотите, чтобы результат не изменился после его первого значения.

И вот что вы получаете. Удалить финал.

+0

final boolean result is predal, он есть как переменная метода просто так, чтобы я мог записать результат вызова функции. Он не предназначен для изменения после его установки, поэтому причина для финала. – spanky762