Java 在递归方法中如何返回值?[爪哇]

Java 在递归方法中如何返回值?[爪哇],java,recursion,switch-statement,return-value,boolean-expression,Java,Recursion,Switch Statement,Return Value,Boolean Expression,TLDR:java似乎只在方法运行时返回第一个值。这是我错了,还是有一个我不知道的解决方法[不使用循环] 我的目标是从分配给方法的返回中输出最后一个值[boolean],但是如果没有正确理解返回的工作原理,我就无法这样做 代码的目的是通过读取用户输入从简单的选择[Y/N]返回布尔值。如果给出错误的输出[例如:“p”、“p”、“apples”],该方法应再次提示用户,直到给出正确的输入 这就是我开始的原因: private Boolean nrCheck() { Scanner s

TLDR:java似乎只在方法运行时返回第一个值。这是我错了,还是有一个我不知道的解决方法[不使用循环]

我的目标是从分配给方法的返回中输出最后一个值[boolean],但是如果没有正确理解返回的工作原理,我就无法这样做


代码的目的是通过读取用户输入从简单的选择[Y/N]返回布尔值。如果给出错误的输出[例如:“p”、“p”、“apples”],该方法应再次提示用户,直到给出正确的输入

这就是我开始的原因:

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" :              isNewRelease = true;  break;
        case "N" : case "n" :              isNewRelease = false; break;
        default  : /*Try again*/ nrCheck();                      break; 
    }

    return isNewRelease;
}
显然这不起作用,因为默认情况下不赋值, 导致初始化错误。

试图通过指定默认值来修复此问题,如下所示:

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" :        isNewRelease = true;            break;
        case "N" : case "n" :        isNewRelease = false;           break;
        default  : /*printTryagain*/ isNewRelease = null;  nrCheck();break; 
    }

    return isNewRelease;
}
这提出了一个新问题。出于某种原因,当我再次调用该方法时,返回值已经设置好了。我试着按照代码的顺序来处理,但实际上并没有多大作用。我的推测是,一旦你回忆起这个方法,返回值就会自动设置,如果第一次设置,你就不能更改它

我知道我可以做到这一点

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    do 
    {
        switch (movieType)
        {
            case "Y" : case "y" :        isNewRelease = true;            break;
            case "N" : case "n" :        isNewRelease = false;           break;
            default  : /*printTryagain*/ isNewRelease = null;  nrCheck();break; 
        }
    }
    while (movieType.equalsIgnoreCase("Y") || movieType.equalsIgnoreCase("N"))

    return isNewRelease;
}
但我个人不愿意这样做,除非我完全意识到没有其他解决方案,或者我的代码中没有明显的错误。[还希望扩展此代码,使其更具通用性]


最终,我希望能够理解我犯了什么错误,或者如果没有任何错误,在这种情况下返回的限制,即使这意味着我必须放弃代码进行do-while循环

您应该返回递归调用返回的值:

private boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);

    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" : return true;
        case "N" : case "n" : return false;
        default  : return nrCheck();
    }
}
如果忽略该值,那么首先进行递归调用是没有意义的


另外,您可能可以将该方法的返回类型更改为
boolean
,因为它永远不会返回
null

我认为您甚至不需要在这里使用递归,而且您似乎理解了它的错误用途。第三次尝试使用
do
循环是轮询用户输入的典型方式:

private boolean nrCheck() {
    Scanner sc = new Scanner (System.in);
    boolean isNewRelease;

    System.out.println("New Release [Y/N]? ");      
    menuRedirect(movieType);    // don't know what this is doing...

    do {
        String movieType = sc.nextLine();
    } while (!movieType.equalsIgnoreCase("Y") && !movieType.equalsIgnoreCase("N"));

    // at this point, the movie type can only be y/Y/n/N
    isNewRelease = movieType.equalsIgnoreCase("Y") ? true : false;

    return isNewRelease;
}

只需对您的方法做一些小的更改,如下所示

private Boolean nrCheck() {

    Scanner sc = new Scanner(System.in);
    Boolean isNewRelease = null;


    //While loop here which break only if isNewRelease value is 
    //Non null(true or false)
    while (isNewRelease == null) {

        System.out.println("New Release [Y/N]? ");
        String movieType = sc.nextLine();

        menuRedirect(movieType);

        switch (movieType) {
            case "Y":
            case "y":
                isNewRelease = true;
                break;
            case "N":
            case "n":
                isNewRelease = false;
                break;
            default:
                System.out.println("Try Again");
                /*I removed recursive call which not required because recursive calls always creates new stack frames so it is recommenced that if we are going to use such calls we need to go with tail recursion.*/    
                isNewRelease = null;
                break;
        }

    }

    return isNewRelease;
}

你应该解释你做了哪些改变,这还不清楚。告诉我原因,好的。我只想简单一点,谢谢你的回复。然而,这似乎类似于我问题中的第二个代码块,主要区别在于您在一开始也实例化了isNewRelease。我已经尝试过了,但没有成功,返回的值为null。我选择不提这件事的唯一原因是因为我的问题太大了。啊,我知道你现在做了什么。抱歉没有注意到这一点:)这似乎正是我要找的!然而,我有点困惑,因为一个布尔值实际上不是从nrCheck返回的?Java是否理解最终返回布尔值的意图,并覆盖初始化错误,直到满足条件并返回布尔值?@rubyduby我不确定我是否理解您的问题。我的答案中的switch语句在所有可能的执行分支中都包含一个return语句。因此,该方法保证返回一个布尔值。既然返回的值必须是布尔值,那么考虑到nrCheck不是布尔值,为什么nrCheck是一个有效的返回值?如果返回相同的方法,是否有异常?
nrCheck()
返回一个
布尔值(或者布尔值,如果将方法的返回类型更改为
布尔值
),因此
返回nrCheck();返回一个
Boolean`@rubyduby@rubyduby我将方法的返回类型更改为
boolean
,以防引起混淆。但是,Java可以在必要时自动将布尔值框到布尔值,并自动将布尔值取消框到布尔值。然而,这与我的问题无关,所以我将删除它。谢谢你指出这一点。然而,我应该提到我的误解是我首先提出这个问题的原因[我试图在我的问题中多点指出这一点];这个答案没有解决我的理解不正确的问题。@rubyduby我认为你不应该在这里使用递归,我已经回答了这个问题。如果你有其他一些问题,使用递归是有意义的,那么编辑你的问题。Biegelesien也许这个解决方案没有递归会更好,但最终这不是我的问题。为了清楚起见,我在最后两行中重申了这一点。