我遇到了这样一个例子,并大致画了它,因为我了解Java机器的计算。我知道在代码中使用它很糟糕,但是,在解决面试的各种测试时,我经常会遇到这样的问题。我将非常感谢向我解释我的推理是否正确的人。
public class DeleteThis {
static int a = 1111;
static {
a = a-- - --a;
// 1111 = (1111 - (отложенный 1)) - 1111
// 1110 1109
// a = 1111 - 1109 ???
}
public static void main(String[] args) {
System.out.println(a);
// 2
}
}
也就是说,尽管我们有更高的优先级预减量,但它降低了它的 (a) 值作为第二个值。在这种情况下,在计算中仍然没有考虑到第一个。
为了弄清楚它是如何工作的,我们需要语言规范中的这些规则:
15.17.1首先计算左手操作数
15.7.2运算前评估操作数
15.14.3后缀减量运算符 --
15.26.1。简单赋值运算符 =
在这里,我将其减少到必要的最小值(基本上我错过了错误行为的描述 - 这与我们的示例无关)
为了评估
a = a-- - --a等价a = ((a--) - (--a))且是赋值的表达式的值,根据 15.26.1,必须要根据 15.7.2 评估表达式
(a--) - (--a),必须评估参数。此外,根据 15.17.1,它们必须从左到右计算。因此,第一个是计算出来的a--。a--根据 15.14.3的计算以这样一种方式发生,即表达式的值(即,-在我们的例子中,操作的第一个参数将是变量 的初始值a,即1111),但在计算表达式的过程中,变量a将被赋予一个新值,即1110。请注意,此赋值发生在计算表达式时a--,即 在计算要减去的第二个参数之前。接下来,计算减法运算的第二个参数。此时,变量
a已经分别等于1110,表达式的值--a(因此减法的第二个参数)将是,并且在表达式的计算过程1109中将写入相同的值。a下一步是实际的减法 (1111 - 1109) 并从赋值操作执行步骤 3。结果,该
a值将被写入2.