简体   繁体   中英

Java: boolean primitive private method returning false even though set to true

I have a public method which calls a private method, which conditionally calls another private method. All three methods return a boolean primitive value, however the value is sometimes changing from what I expect it to be.

I am certain I am missing something incredibly obvious, but I am now too close to the code to see the problem.

Here is a cleaned up sample version of the code and the results I am seeing:

EDIT: I have added the ACTUAL code at the bottom

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

Calling Code:

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

Console Output:

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

In the sample above, the value of result gets set to true in method dowsers(), and is correctly returned to bar(). When bar() tests the returned value from wowsers() and finds it to be true it sets it's own result to true and prints to the console the value of result and prints that dowsers() returned a true.

The System.out.println at the end of bar() is NEVER executed (at least I never see anything show up in the console), and the value of result (which at this point is true) is returned as false.

The foo() method then prints the value it received from the call to bar, which is always false.

Does anybody see where I'm messing up?

EDIT: Here is the ACTUAL code -replaces methods foo() and bar()

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;
}

The Console Output I am getting is:

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

(I realize I should have posted the ACTUAL code in the first place)

For some reason I cannot figure out, it seems as though the final two lines of code in method bar() and method sendNotification() do not appear to be running. Is there some other way for a method to complete and return that I am unaware of?

I suggest you put a debug print statement before this line:

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

Since this is in a while loop, and allows the method to return false even though result has been set true. I'll bet this is where the false return is coming from, and why you don't see the final print statements being executed.

Read this :

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

In this method

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;
}

You re-instantiate boolean varaible. This is a new boolean result outside of scope method bar

Simply block. Just think.

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

And finally it looks like a

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

so you return false

final boolean result

This means you want result will never change after its first value.

And that's what you get. Remove final.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM