我试图理解null
在Java中是如何工作的。
如果我们将null
分配给任何对象,那么场景背后会发生什么?它是否指定了指向null
“对象”或其他内容的内存位置地址?
我已经尝试了以下程序,并且我已经明白所有null
都指向同一位置。
但有人能告诉我Java如何抛出NullPointerException
以及null
如何在Java中运行?
class Animal{
}
class Dog{
}
public class testItClass {
public static void main(String args[]){
Animal animal=null;
Dog dog=null;
if(((Object)dog) == ((Object)animal))
System.out.println("Equal");
}
}
输出
相等。
答案 0 :(得分:4)
如果我们将null分配给任何对象,它实际上是堆中的一些内存位置或其他任何东西。
应该区分reference
和object
。您可以将null
分配给参考。
通常使用new
运算符在堆中创建对象。它返回一个对象的引用。
A a = new A();
在堆中创建类型为A
的对象。您将获得返回参考a
。如果现在你指定
a = null;
对象本身仍驻留在堆中,但您无法使用引用a
访问它。
请注意,以后可能会对对象进行垃圾回收。
<强> UPD:强>
我创建了这个类来查看它的字节代码(第一次给我):
public class NullTest {
public static void main (String[] args) {
Object o = new Object();
o = null;
o.notifyAll();
}
}
它产生:
C:\Users\Nikolay\workspace\TestNull\bin>javap -c NullTest.class
Compiled from "NullTest.java"
public class NullTest {
public NullTest();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #3 // class java/lang/Object
3: dup
4: invokespecial #8 // Method java/lang/Object."<init>":()V
7: astore_1
8: aconst_null
9: astore_1
10: aload_1
11: invokevirtual #16 // Method java/lang/Object.notifyAll:()V
14: return
}
您可以看到将null设置为参考结果:
8: aconst_null
9: astore_1
List of byte code instructions
基本上它将null值放在堆栈顶部,然后保存到引用。但是这种机制和参考实现是JVM内部的。
答案 1 :(得分:1)
以下声明对类Animal
(或其子类)的对象的引用,并将其初始化为null
:
Animal animal = null;
这里,引用本身占用了一些空间。由于没有关联的对象,因此没有进一步的内存成本。
如果您尝试通过访问对象来使用null
引用:
Animal cat = null;
if (cat.equals(dog)) { ... } // throws NPE
你会得到NullPointerException
。
然而,只要您不尝试取消引用它,就可以对null
引用本身进行操作:
Animal cat = null;
Animal dog = null
if (cat == dog) { ... } // works fine
答案 2 :(得分:1)
java中的Null是基于NULL Object模式设计的。
NULL对象表示不存在的对象。如果我们尝试从这个不存在的对象访问任何资源,我们不应该得到任何东西,这在逻辑上是有道理的。但实际上像Java这样的编程语言会创建NullPointerException类的实例,并将所需的信息填充到Object中并抛出调用语句。
答案 3 :(得分:0)
Null实际上是对任何内存的引用(因此为null)。代码中的所有对象引用都是指向保存物理数据的内存中的位置的指针。如果一个对象为null,则它没有引用,或者在内存中没有任何指向。这就是为什么null除了检查它是否为空之外不能用于其他任何东西。
当尝试操作没有物理内存引用的对象时,Java将抛出一个空异常。
答案 4 :(得分:0)
它输出true,因为null == null
空无意义。
Animal animal=null;
定义对Animal
对象的引用,但尚未分配给它,因此它指向任何内容。
如果您有使用C / C ++的经验,就像设置指向NULL
或nullptr
的指针。
答案 5 :(得分:0)
当一个对象设置为null
时,基本上它在JVM中没有内存引用。此外,两个空对象之间的==
比较也会产生真值。
答案 6 :(得分:0)
Java中只有一个null
。它出现在所有情况下都是一样的,无论变量如何,甚至不论类别如何。编译器不允许直接比较,但你可以投射:
String x = null;
ArrayList a = null;
if ((Object) x == (Object) a) {
System.out.println("Do not have onther nulls, only ME");
}
答案 7 :(得分:0)
在字节码级别上有一条指令来推送&#34; null&#34;到本地堆栈(然后将其分配给可变插槽或字段)。
大多数Java虚拟机实际上使用分配给null的实际(机器)指针。因此,如果使用它们,它们会在内部捕获信号(SIGSEGV)并将其转换为NPE。你可以通过发送&#34; kill -SEGV&#34;来测试这个。对于Java PID,它将在大多数时间生成随机NullPointerExceptions。