这样做是不好的做法:
Scanner scan = new Scanner(System.in);
if(scan.nextInt() == 5) { //testing if input is equal to 5
System.out.println("input equals 5");
}
怎么样:
Scanner scan = new Scanner(System.in);
if(scan.nextInt() == scan.nextInt()) { //testing if two inputted ints are equal to each other
System.out.println("input1 equals input 2");
}
我在某处读到这会导致“意外结果”,但我不知道这意味着什么。我已经对此进行了相当多的测试,并没有遇到任何意外情况。
答案 0 :(得分:5)
这里的问题不在于您在if
块的条件内调用方法。问题是你的功能不是纯,即它有副作用。如果您查看@Krayo的示例,您将看到两个看似相等的代码片段如何具有不同的行为:&&
仅执行第二个表达式,如果第一个表达式求值为true
。类似地,||
仅执行第二个表达式,如果第一个是false
。
查看Command and Query separation原则。它声明您的方法应该计算并返回一个值,或者它们应该更改对象的状态,但不能同时更改两者。
修改:另请参阅Uniform Access原则。程序的语义不应取决于您是通过存储还是通过计算获得值。如果您的程序在访问字段时的行为与执行计算相同值的方法的行为不同,那么您应该修复方法。 注意:行为和性能是两双鞋:访问字段比计算值更快。
答案 1 :(得分:3)
在if / else中调用方法并不错。它很好,尤其是当它返回一个你只需要一次的值时。
答案 2 :(得分:1)
意外结果的一个例子:
public static int count;
public static void run1() {
count = 0;
long r1 = getNum1();
long r2 = getNum2(); // it is called in any case, so count = 1
if (r1 == 1L && r2 == 0L) { /* if r1 = 1 and r2 = 0 then print "blah"
if r1 = 0 then r2 is not checked! (lazy evaluation) */
System.out.println("blah");
}
System.out.println(count); // always print 1 (count = 1)
}
public static void run2() {
count = 0;
if (getNum1() == 1L && getNum2() == 0L) { /* if getNum1() = 1 and getNum2() = 0 then print "blah"
if getNum1() = 0 then getNum2() is not checked, so count = 0! */
System.out.println("blah");
}
System.out.println(count); // depends on the getNum1() result
}
// return 0 or 1 depending on milliseconds of the current time is even or odd
public static long getNum1() {
return System.currentTimeMillis() % 2L;
}
// same as getNum1() and addition set count to 1
public static long getNum2() {
count = 1;
return System.currentTimeMillis() % 2L;
}