Java,我不明白为什么会发生这种变化

时间:2017-11-08 20:25:34

标签: java variables random methods

    public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");
    String enteredDate = in.nextLine();

    //This array will hold the 3 elements of which the date is made up of, day, month and year, and this method returns it.
    String[] dateEnteredSplit = enteredDate.split("/");

    //I am using the split method to seperate each number, which returns an array, so I am assigning that array to the dateEnteredSplit array.
    //dateEnteredSplit = enteredDate.split("/");
    //So now the first element holds the day, second the month, and the third element holds the year.

    //System.out.println(Arrays.toString(dateEnteredSplit));

    //Assigning each element and converting them to integers.
    int day = Integer.parseInt(dateEnteredSplit[0]);
    int month = Integer.parseInt(dateEnteredSplit[1]);
    int year = Integer.parseInt(dateEnteredSplit[2]);

    **System.out.println("day: " + day + "  month: " + month + "  year: " + year);**

    //The loop will be entered if any of the values are wrong. which will use recursion to call this method again for a chance to enter the date again.
    while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) {
        **System.out.println("day: " + day + "  month: " + month + "  year: " + year);**
        //Im calling these methods to inform which one specifially was wrong so they know what they need to change.
        this.setDay(day);
        this.setMonth(month);
        this.setYear(year);

        dateEnteredSplit[0] = "0";
        askForDate(in);
    }

    //I then assign any correct value into the object attribute because the while loop is either finished or not entered at all. 
    //No need to use setDay etc. here because the checks have been done above in the while loop.
    this.day = day;
    this.month = month;
    this.year = year;  
}

好的,这是一个类中的方法。它要求输入格式为dd / mm / yyyy

如果我第一次输入12/1/1996它可以工作,但是如果我输入错误的日期,例如第一次,123/123/03,并输入正确的日期,例如12/1/1996,它仍然进入循环。

调试后,第一行是粗体,值与粗体的第二行不同,就像值自己改变一样。

这是什么问题?我一直试图在过去1小时内找到答案。

提前致谢!

2 个答案:

答案 0 :(得分:0)

问题很可能在于你试图将递归和迭代方法结合到更新值的方式(有一个while循环,它递归地调用函数,这也可能在下一级调用和前一个循环中触发一个人将继续以递归的方式自我调用,你最终只会陷入混乱)

没有真正的理由以递归的方式做到这一点,我会做迭代式的方法,就像这样:

public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");

    int day, month, year;
    do { // We use do-while to get the first read without condition, although setting date to invalid value (like day = 0) and then running standard while loop will work just as fine
        String[] dateEnteredSplit = in.nextLine().split("/");

        //Assigning each element and converting them to integers.
        day = Integer.parseInt(dateEnteredSplit[0]);
        month = Integer.parseInt(dateEnteredSplit[1]);
        year = Integer.parseInt(dateEnteredSplit[2]);
    } while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000));

    // Now day month and year variables are set correctly and we can do stuff with it
}

如果你坚持或递归方法,正确的方法是只调用一次函数:

public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");

    int day, month, year;
    String[] dateEnteredSplit = in.nextLine().split("/");

    //Assigning each element and converting them to integers.
    day = Integer.parseInt(dateEnteredSplit[0]);
    month = Integer.parseInt(dateEnteredSplit[1]);
    year = Integer.parseInt(dateEnteredSplit[2]);

    if (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) askForDate(in);

    // You need to save day/month/year variables to other than local scope (like this.day = day)
    // Otherwise it would just somewhere in recursion stack and you wouldn't be able to use it
}

要完成,请记住,日期字符串可能是错误的,只是编号超出范围。如果用户输入1. 2. 3456a/b/c或者甚至没有像Hello那样非常不同的内容,该会怎样 在您的代码片段崩溃时(在尝试解析非整数时抛出NumberFormatException或在不存在的元素访问ArrayIndexOutOfBoundsException数组时抛出dateEnteredSplit(在'中没有'/'你好'))

答案 1 :(得分:0)

以下是发生的事情。第一次while循环迭代的错误值可以调用askForDate。您收到第二个提示并提供正确的输入。 askForDate的第二次调用按预期结束。执行再次返回到while循环,您仍然有第一个错误设置的值,并且该过程再次开始。

如果你真的想在这里使用递归,你应该从函数中返回一个值(日期或布尔标志)并在while循环条件下检查它。