gpt4 book ai didi

java - 澄清 StringBuilder 引用和方法执行顺序

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:20:38 25 4
gpt4 key购买 nike

这段代码

    StringBuilder b1=new StringBuilder("hello");
b1.append(b1.append("!"));
System.out.println("b1 = "+b1);

将打印

    b1 = hello!hello!

因为内部的append先被执行并修改了对象b1;然后对外部 b1 求值(现在它等于 hello! )并将相同的字符串附加到它。所以

  1. 执行内部表达式
  2. 原始对象被修改
  3. 外部表达式在修改后的对象上执行

但是现在,为什么这段代码会抛出 NullPointerException

    StringBuilder s1=null;
StringBuilder s2=new StringBuilder("world");
try{s1.append(s1=s2.append("!"));}
catch(Exception e){System.out.println(e);}
System.out.println("s1 = "+s1+"\ns2 = "+s2+"\n");

并打印

    java.lang.NullPointerException
s1 = world!
s2 = world!

我期望引用 s1 指向 s2 引用的对象 before 外部 append被执行。

在某种程度上,分配 b1.append("!"); 会影响“外部”b1,但是 s1=s2.append("! ") 没有。我知道这是因为在第一种情况下我正在修改对象,而在第二种情况下我正在修改引用但是......评估和执行值/引用/方法的顺序是什么?

编辑

同样的事情发生在数组上:

    int[] y = { 0, 0, 0 };
try {y[y[0] = 2] = 4;}
catch (Exception e) {System.out.println(e);}
System.out.println("y = "+Arrays.toString(y)+"\n");

打印

    y = [2, 0, 4]

同时

    int[] x1 = null;
int[] x2 = { 1, 2, 3 };
try {x1[(x1=x2)[0]] = 0;}
catch (Exception e) {System.out.println(e);}
System.out.println("x1 = "+Arrays.toString(x1)+"\nx2 = "+Arrays.toString(x2));

打印

    java.lang.NullPointerException
x1 = [1, 2, 3]
x2 = [1, 2, 3]

最佳答案

这是在 JLS 15.12.4 中指定的:

If form is ExpressionName . [TypeArguments] Identifier, then:

  • If the invocation mode is static, then there is no target reference. The ExpressionName is evaluated, but the result is then discarded.

  • Otherwise, the target reference is the value denoted by ExpressionName.

As part of an instance method invocation (§15.12), there is an expression that denotes the object to be invoked. This expression appears to be fully evaluated before any part of any argument expression to the method invocation is evaluated.

所以在行 s1.append(s1=s2.append("!")); s1 (在 .append(s1 = .. .)) 在参数表达式 s1=s2.append("!") 之前先求值。因此,在将 s1 更改为引用 StringBuilder s2 实例之前,null 引用被记住为目标引用。

然后对参数表达式求值,以便执行 s1=s2.append("!")。但是它记住了之前的目标引用,所以在 null 引用上调用了 append 方法,调用的结果抛出一个 NullPointerException

关于java - 澄清 StringBuilder 引用和方法执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31635378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com