String str1;
String str2 = null;
String str3 = "";
String str4 = new String();
String str5 = new String("");
我知道对于上面的第3次初始化,字符串对象在字符串池中初始化,而第4次与字符串池无关。
1之间有什么区别?和2。?如果我将str1
视为指针变量,它存储的是一个从未被JVM或OS使用的特定内存地址?
4之间是否存在差异?和5. ?
当我str1
和str2
直接打印System.out.println(str1)
和System.out.println(str2)
时,对于str1
,我甚至无法通过编译。 str2
,编译没问题,我得到" null"和控制台窗口中的输出。为什么呢?
在@aioobe回答之后编辑:更多问题:
我想了解更多关于" null"。由于str2
(引用变量)就像一个指针变量,因此它应该有一些东西(0/1位)(在这个指针变量占用的内存中)。当它被初始化为null时,它是全0位还是null的字节码全为零?另一个问题是如果我通过str2
在str2.toString()
上调用方法toString(),我在运行时得到了NullPointer错误。那么JVM是否检查引用变量是否为空? JVM如何知道它是null? JVM检查str2
?
Java中有关 null 的另一个问题: concatenation of null and a string literal
答案 0 :(得分:16)
1.和2.有什么区别?如果我将
str1
视为指针变量,它存储的是一个从未被JVM或OS使用的特定内存地址?
如果这些是类中的字段,则没有区别,因为引用类型字段(例如String)的默认值已经是null
。
如果这些局部变量(即在方法中声明的变量)str1
将不会初始化为任何内容,而str2
将初始化为null
。这里的区别在于局部变量在初始化之前无法使用,因此(您似乎已经发现)无法打印str1
,但您可以打印str2
。< / p>
4和5之间有区别吗?
不,不是语义上的。你会得到略有不同的字节码。
当我直接通过System.out.println(str1)和System.out.println(str2)打印str1和str2时,对于str1,我甚至无法传递编译。对于str2,编译是正常的,我在控制台窗口中得到“null”和输出。为什么呢?
这似乎表明这些是局部变量。局部变量需要在使用之前进行初始化。
我想了解更多关于“null”的信息。由于
str2
(引用变量)就像一个指针变量,因此它应该有一些东西(0/1位)(在这个指针变量占用的内存中)。当它被初始化为null
时,它是全0位还是null
的字节码全为零?
这已被问及(并已回答):
另一个问题是,如果我通过
toString()
在str2
上调用方法str2.toString()
,我在运行时会遇到NullPointer错误。因此,JVM会检查引用变量是否为null
?
是
JVM如何知道它是
中的位null
? JVM检查str2
?
是
答案 1 :(得分:1)
Java中表示对象的每个变量实际上都不是值,而是指向存储该变量的内存中某个位置(地址)的指针。 null
是一种特殊类型的指针,表示变量(指针)已初始化但未指向任何内容。
因为任何两个String变量都是指针,如果你将它们比作str1 == str2
,你会检查它变量指向同一个实例。要比较内容,指针指向您需要使用等于:str1.equals(str2)
,但在这种情况下,我们必须确保str1不是null
。