1

有很多关于 null 和 in java 的问题。

我无法理解的是人们所说的 null 是什么意思,或者根本没有指向任何东西或为什么要使用 null。

我无法理解两者之间的区别

String thing = null;

String thing = "";

这个问题有详细的答案Java中什么是null?,但我就是无法绕过它。

我错过了什么?


我学过的语言(没有专家)

Python, vb (vb.net), 网页编程 (html, css, php, bit of js), sql

我应该补充一下,正是这个答案https://stackoverflow.com/a/19697058/2776866促使我写了这个。

4

9 回答 9

6
String str = null;

表示一个字符串引用,名为 str,不指向任何东西

String str = "";

表示一个名为 str 的 String 引用,指向一个实际的 String 实例。对于那个 String 实例,它是一个长度为零的 String,但它仍然是一个实际对象。


只需稍微更新一些图表,希望可以帮助您形象化:

假设我有

String nullStr = null;
String emptyStr = "";
String myStr = "ab";

它在概念上是这样的:

  // String nullStr = null;

  nullStr ----------> X    pointing to nothing



  // String emptyStr = "";
                      +------------------+
  emptyStr ---------> |       String     |
                      +------------------+
                      | length = 0       |
                      | content = []     |
                      +------------------+


  // String myStr = "ab";
                      +------------------+
  myStr ------------> |       String     |
                      +------------------+
                      | length = 2       |
                      | content = [ab]   |
                      +------------------+

(当然String对象的内部结构并不是Java中真实的东西,只是给大家一个思路)


更多关于 NULL 背后原理的编辑:

事实上,在某些语言中,它们不提供 NULL 的概念。无论如何,在 Java(或类似语言)中,Null 意味着在语义上与“空”对象不同。以 String 为例,我可能有一个People带有 StringpreferedTitle属性的类。NullpreferedTitle表示该人没有首选标题(因此我们可能需要为其派生和显示标题),而preferedTitle作为空字符串表示存在首选标题,并且没有显示任何内容。

顺便说一句,虽然有点离题:Null 的概念对某些人来说被视为有问题(因为它需要所有额外的处理等)。因此,一些语言(例如 Haskell)正在使用其他一些方法来处理我们过去使用 Null 的情况。

于 2013-10-31T02:02:46.603 回答
4

Java doesn't really expose pointers, instead it deals with references.

When you say

String thing = null;

You are saying that there is a reference (of type string) called thing, which isn't referencing anything.

When you say

String thing = ""

This is shorthand for,

String thing = new String("");

Now you have an actual object initialized and ready to be used. You told the compiler to create a string and now your "thing" references the new string.

If you want to know the length of your initialized string, you can go;

thing.length

Which is zero. The string exists, but is zero length.

Trying string.length on the null version causes a NullReferenceException, which is the compiler saying

"I tried to find out about the length of your string, but I couldn't find it!"

于 2013-10-31T02:05:43.333 回答
4

String str is a reference to an object. That is, it's not an actual object, but a variable which can contain the address of an object. When you assign a value to str you are changing the address stored within and changing which object it addresses.

null is reference value which points to no object. It's about as close to nothing as you can get. If you assign null to a String reference (String str = null;), you cannot then invoke any method of String using that reference -- all attempts will result in NullPointerException.

"" is a character String which contains no characters -- zero length. It is still an object, though, and if you assign its address to your String reference variable (String str = "";) you can then take its length, compare it to another String, extract its hashCode, etc.

于 2013-10-31T02:11:21.113 回答
3

实际上,null意味着“不可用于调用方法”。如果一个对象是允许的null,你必须null在调用它的方法之前检查它。

尝试调用null对象上的任何方法都是无条件的错误。在几乎所有情况下,这也是一个编程错误,因为您应该

  • 确保变量始终为非空,或
  • null在调用方法之前检查一个可能合法存在的变量。

另一方面,空对象允许您调用方法。例如,您可以找到一个空字符串的长度 - 它为零。您还可以迭代一个字符串,将其传递给需要非空字符串的方法,等等。

为了可视化这一点,请考虑一个Boolean对象而不是String. 与boolean只有两种状态(即true(“yes”)和false(“no”)的原语不同,Boolean对象具有三种状态:

  • 是的
  • 不知道

这第三个“不知道”状态对应于null。它既不是true也不是false状态。您的程序可以充分利用这第三种状态 - 例如,您可以使用比较来null查看是否已设置值,或将值设置null为“取消设置”其值。

于 2013-10-31T02:08:05.343 回答
2

从概念上讲null是一个特殊值,这意味着变量指向一个无效对象,因此它不引用任何有效的东西,因为您无法访问其内容(变量或方法)。

您可以将其视为一种已添加到语言中的特殊条件,因为能够拥有不引用任何内容的指针很有用。但是这里有一些不一致,事实上,有些语言null通过强迫你只具有初始化(有意义的)值来阻止值的必要性。

您的示例有所不同,""它是一个有效对象:它是一个空字符串,而null不是一个有效对象。

于 2013-10-31T02:08:13.483 回答
2

让我们将其与 Python 进行比较。null在 Python中,等价于None.

>>> test = ""
>>> test1 = None

这是设置一个空字符串和一个“null”字符串。

>>> test
''
>>> test1
None

在 Python 中,我们可以使用is

>>> test is None
False
>>> test1 is None
True

我们可以使用测试空字符串==

>>> test == ""
True
>>> test1 == ""
False

null(like None) 是没有值。

于 2013-10-31T02:15:35.050 回答
2

在 Java 中,null 和空字符串是两个不同的东西。

如果 String 为 null,则您无法访问其方法,因为它将抛出 NullPointerException,但是如果 String 为 null,则""String 对象有效,您可以访问其方法。

例如

 String a = null;
 String b = "";

 System.out.println (a.length());   // No Good
 System.out.println (b.length());   // Prints 0
于 2013-10-31T02:03:25.740 回答
2

尽管许多面向对象的框架使用指针实现引用,但最好不要将引用视为“指向”对象,而是将其视为“标识”它们[个人而言,我喜欢用术语“对象标识符”来描述引用,因为术语“参考”在不同的上下文中有些过载]。尽管对象标识符不是人类可读的,但可以将系统想象为给每个对象一个从 1 开始的关联编号,并且每个类类型变量都具有对象编号或写在其上的零。由于类类型变量和数组槽默认保持为零,并且永远不会有第零个对象,因此未初始化变量或数组槽的默认值变量不会识别有效对象。

于 2013-11-04T18:58:30.067 回答
0

我更喜欢使用容器/盒子的概念来理解这个概念

让我们从这个开始

String thing = "";

想象一下,你有一个容器/盒子,只要你把值放在双引号“”之间,你就可以存储任何值,如果你决定只在盒子里放一个没有值的双引号,那绝对没有错并且任何时候你打开你的盒子你仍然会看到里面的东西(双引号)

现在这里的这个大个子叫null

String thing = null;

简单来说,将 null 视为绝对没有

这是什么意思呢?当您打开第一个框时,您会看到双引号“”

当您打开第二个盒子时,您什么也看不到(它只是一个空盒子)

于 2021-12-20T01:38:25.417 回答