Why is this not throwing a NullPointerException?
NEAD对以下代码的澄清:
1 2 3 4 | StringBuilder sample = new StringBuilder(); StringBuilder referToSample = sample; referToSample.append("B"); System.out.println(sample); |
这将打印
1 2 3 4 5 | StringBuilder sample = new StringBuilder(); StringBuilder referToSample = sample; sample.append("A"); referToSample.append("B"); System.out.println(referToSample); |
这将打印也证明相同的
1 2 3 4 5 | StringBuilder sample = new StringBuilder(); StringBuilder referToSample = sample; referToSample = null; referToSample.append("A"); System.out.println(sample); |
显然,这将抛出
1 2 3 4 5 | StringBuilder sample = new StringBuilder(); StringBuilder referToSample = sample; referToSample = null; sample.append("A"); System.out.println(sample); |
所以我的问题是,为什么最后一个代码示例没有抛出
为了简单起见,我们假设地址通常用1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | StringBuilder sample = new StringBuilder(); //sample refers to //StringBuilder at 12345 StringBuilder referToSample = sample; //referToSample refers to //the same StringBuilder at 12345 //SEE DIAGRAM 1 referToSample = null; //referToSample NOW refers to 00000, //so accessing it will throw a NPE. //The other reference is not affected. //SEE DIAGRAM 2 sample.append("A"); //sample STILL refers to the same StringBuilder at 12345 System.out.println(sample); |
从标有
图1:
1 2 3 | [StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345] ↑ [StringBuilder referToSample] ------------------------/ |
图2:
1 2 3 | [StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345] [StringBuilder referToSample] ---->> [null pointer] |
图2表明,取消
1gc考虑因素使这不可信。
最初,正如您所说,
1。情景1:
2。场景1(续):
这里,因为
referToSample 指的是sample ,所以加上了"b"当你写作的时候referToSample.append("B")
同样的事情发生在场景2:
但是,在3。场景3:正如六分之一所说,
当你把
现在,由于
但
简而言之:您将空值赋给一个引用变量,而不是一个对象。
在一个示例中,您可以更改由两个引用变量引用的对象的状态。当发生这种情况时,两个引用变量都会反映出变化。
在另一个示例中,您更改了分配给一个变量的引用,但这对对象本身没有影响,因此仍然引用原始对象的第二个变量将不会注意到对象状态的任何更改。
至于你的具体"规则":
if two objects referring to same object then if we change any value then it will also reflect to other because both are pointing to same memory reference.
同样,您也提到更改两个变量所引用的一个对象的状态。
So why is that rule not applying here? If I assign null to referToSample then sample should also be null and it should throw nullPointerException but it is not throwing, why?
同样,更改一个变量的引用,这对另一个变量的引用绝对没有影响。
这是两种完全不同的行为,将导致两种完全不同的结果。
见下图:
当您在
这里的'sample'和'referetosample'引用的是同一个对象。这是不同指针访问同一内存位置的概念。因此,将一个引用变量赋给空不会破坏对象。
1 | referToSample = null; |
表示"referToSample"只指向空值,对象保持不变,其他引用变量工作正常。所以对于不指向空并且具有有效对象的"sample"
1 | sample.append("A"); |
工作良好。但如果我们尝试将空值附加到"referToSample",它将显示nullpointException。也就是说,
1 |
这就是为什么在第三个代码片段中出现nullpointerException。
很简单,Java没有传递引用,它只是通过对象引用。
每当使用一个新关键字时,它都会在堆中创建一个对象。
1)StringBuilder示例=new StringBuilder();
2)StringBuilder referToSample=示例;
在2)referesample的引用是在同一对象样本上创建的。
因此referToSample=空;仅使引用的样本引用无效这就是为什么您没有得到空指针异常的原因。感谢Java的垃圾回收