Search code examples
javareturn

Java Newb: Return parameter not reassigned after recursive loop


    static String ask(String question) {

        String Answer = JOptionPane.showInputDialog(question);
        Answer = Answer.toUpperCase();

        System.out.println("User, " + counter +"," + Answer); // for debugging purposes
        counter += 1; // for debugging purposes

        switch (Answer){

        case "A":
            return(Answer);
        case "B":
            return(Answer);
        case "C":
            return(Answer);
        case "D":
            return(Answer);
        case "E":
            return(Answer);
        default:
            JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
            ask(question);
            // when invalid option entered, we loop back to beginning of method - Answer not being reassigned

        }
        return(Answer);  // I don't need this, Java won't let me run without it

after entering a few invalid entries, the parameter returned isn't reassigned with the valid entry. example of output:

User, 1,U
User, 2,I
User, 3,O
User, 4,P
User, 5,M
User, 6,A
User Answer:U
CorrectAnser:A
false

As you can see, "U" was the first entry, and the last - "A" is the entry that escaped the loop. Though "U" is what's returned and not "A." Can't figure out why?


Solution

  • As Ivar said in the comments, you're not returning the answer in the default part of your switch statement. You need to say return ask(question instead of just calling ask(question). Then, the return answer part at the bottom will be unnecessary. See the code below (I've also modified it a bit to look more aesthetically pleasing).

    You should realize that when you call the method again, the return statement only returns from that last method call. Therefore, in your original method call, the result of ask(question) is ignored (it's practically like calling a void method). Return statements don't return to the first method in the stack. That's why you need a return in your default.

    static String ask(String question) {
    
            String answer = JOptionPane.showInputDialog(question).toUpperCase();
    
            System.out.println("User, " + counter +"," + answer); // for debugging purposes
            counter += 1; // for debugging purposes
    
            switch (answer) {
            case "A":
            case "B":
            case "C":
            case "D":
            case "E":
                return answer;
            default:
                JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
                return ask(question);
                // when invalid option entered, call method again (btw, you're not looping back, it's just recursion)
            }
    }
    

    Turned into a loop, this would be:

    static String ask(String question) {
      String result = question;
      do {
        String answer = JOptionPane.showInputDialog(question).toUpperCase();
        switch (answer) {
            case "A":
            case "B":
            case "C":
            case "D":
            case "E":
                result = answer;
                break;
            default:
                JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
            }
      } while (result == question); //I know, I know, I'm using "==". But it should be fine because question is assigned to it at the start
      return result;
    

    Imagine you have a function that takes 2 strings, hashes them both, and then returns true if the hash code of the first is greater than that of the second.

    public boolean compareHashCodes(String s1, String s2) {
      int hash1 = hash(s1), hash2 = hash(s2);
      hash(s1);
      return hash1 > hash2;
    }
    
    public int hash(String s) {
      return s.hashCode(); //or something else
    }
    

    As you can see, when you call the hash method the first time and return an int, that does not mean that compareHashCodes also immediately returns an int. It merely stores that int into the variable hash1. The same happens the second time, when you put a hashCode into hash2. The third time, the value of hash(s1) is ignored, not returned, because returning ints from a method that isi supposed to return booleans would not make sense. It is only when the final statement return hash1 > hash2 is reached that the method compareHashCodes actually returns.