为什么“abc” +空结果 abcnull

发布于 2024-10-12 10:20:25 字数 201 浏览 2 评论 0原文

为什么 "abc" + null 结果 abcnull

String s1 = "abc";
String s2 = null; 
String s3 = s1+ s2;

System.out.println(s3);

结果:abcnull

why "abc" + null results abcnull

String s1 = "abc";
String s2 = null; 
String s3 = s1+ s2;

System.out.println(s3);

Result: abcnull

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

你怎么敢 2024-10-19 10:20:25

因为Java会创建一个 StringBuilders1"abc", 附加到 s2null

根据 StringBuilder.append(String) 的规范 -

If str is null, then the four characters "null" are appended

所以它变成与 "abc" + "null" 相同

让我们看一下你的代码示例(我将它放在一个方法中):

 public static void main(String[] args)
 {
  String s1 = "abc";
  String s2 = null; 
  String s3 = s1+ s2;
  System.out.println(s3);
 }

如果我们看一下字节码(通过调用 javap -c 获得):

public static void main(java.lang.String[]);
  Code:
   0:   ldc #2; //String abc
   2:   astore_1
   3:   aconst_null
   4:   astore_2
   5:   new #3; //class java/lang/StringBuilder
   8:   dup
   9:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   12:  aload_1
   13:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   16:  aload_2
   17:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   20:  invokevirtual   #6; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   23:  astore_3
   24:  getstatic   #7; //Field java/lang/System.out:Ljava/io/PrintStream;
   27:  aload_3
   28:  invokevirtual   #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   31:  return

Java 创建一个 StringBuilder 并将值附加为 s1Strings > 和s2

因此,如果您期待 NullPointerException,那么您必须小心,因为 Java 中的串联会解决这个问题。

旁注:正如 Jon Skeet 所指出的,这最终只是实现细节 - - Java 规范保证 null 在转换为字符串时会变成“null”。然而,这个字节码至少显示了幕后实际发生的事情。

Because Java will create a StringBuilder to append s1, or "abc", to s2, or null.

According to the spec for StringBuilder.append(String)--

If str is null, then the four characters "null" are appended

So it turns into the same as "abc" + "null"

Let's take your code example (I placed it inside a method):

 public static void main(String[] args)
 {
  String s1 = "abc";
  String s2 = null; 
  String s3 = s1+ s2;
  System.out.println(s3);
 }

If we take a gander at the bytecode (gotten by invoking javap -c):

public static void main(java.lang.String[]);
  Code:
   0:   ldc #2; //String abc
   2:   astore_1
   3:   aconst_null
   4:   astore_2
   5:   new #3; //class java/lang/StringBuilder
   8:   dup
   9:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   12:  aload_1
   13:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   16:  aload_2
   17:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   20:  invokevirtual   #6; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   23:  astore_3
   24:  getstatic   #7; //Field java/lang/System.out:Ljava/io/PrintStream;
   27:  aload_3
   28:  invokevirtual   #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   31:  return

Java creates a StringBuilder and appends the values, as Strings, of s1 and s2.

So you have to be careful then, if you were expecting a NullPointerException, because concatenation in Java will skirt the issue.

Side Note: As pointed out by Jon Skeet, this is ultimately just implementation details -- it's the Java spec that guarantees that null, when converted to a String, turns into "null". However, this bytecode at least shows what is actually happening behind the scenes.

不…忘初心 2024-10-19 10:20:25

这正是语言规范所保证的值。来自 JLS 第 15.8.1.1 节 ,其中讨论了用于字符串连接的字符串转换:

现在只需要考虑参考值。如果引用为 null,则将其转换为字符串“null”(四个 ASCII 字符 n、u、l、l)。否则,转换就像通过调用不带参数的引用对象的 toString 方法来执行;但如果调用toString方法的结果为null,则使用字符串“null”。

(您可能有兴趣听说 .NET 采用不同的方法,将空引用转换为空字符串。每种方法都有其优点和缺点 - 我发现 Java 方法对于创建用于调试的字符串更有用,但 .NET在构建要显示给用户或保存到数据文件等的字符串时,该方法更有用)

That's exactly the value that's guaranteed by the language specification. From the JLS section 15.8.1.1, which talks about the string conversions used for string concatenation:

Now only reference values need to be considered. If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l). Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.

(You may be interested to hear that .NET takes a different approach, converting a null reference to an empty string. Each approach has its pros and cons - I find the Java approach more useful for creating a string for debugging, but the .NET approach more useful when building a string to be displayed to a user or saved to a data file etc.)

有木有妳兜一样 2024-10-19 10:20:25

这就是字符串连接的工作原理。

如果您需要避免连接单词“null”,您可以这样做:

String s3 = (s1==null?"":s1) + (s2==null?"":s2);

That's how string concatenation works.

If you need to avoid concatenating the word "null" you can do:

String s3 = (s1==null?"":s1) + (s2==null?"":s2);
回眸一遍 2024-10-19 10:20:25

我不了解java,但从它的外观来看,似乎您正在将 s2 类型转换为 String 对象,然后将 null 转换为 "null “。如果我错了,请纠正我。

i don't know java, but from the looks of it, it seems like you are type casting s2 as a String object which then turns null into "null". Please correct me if i'm wrong.

撧情箌佬 2024-10-19 10:20:25
String s = "a" + null;

理解的

String s = "a" + String.valueOf(null)

编译器是这样

String s = "a" + String.valueOf(null)/* null*/  = "anull";

在你的例子中

String s3 = String.valueOf(s1) + String.valueOf(s2);
s3 = "abc" + "null" // absnull
String s = "a" + null;

compiler understands it as

String s = "a" + String.valueOf(null)

so

String s = "a" + String.valueOf(null)/* null*/  = "anull";

In your example

String s3 = String.valueOf(s1) + String.valueOf(s2);
s3 = "abc" + "null" // absnull
迎风吟唱 2024-10-19 10:20:25

Java中的字符串连接执行自动转换。空字符串将转换为字符串“null”。如需参考,请参阅此页面

空操作数被转换为
字符串文字“null”。

为了避免这种情况,您应该自己检查一个字符串是否为空。

String Concatenation in Java executes automatic conversion. The null string will be converted to the string 'null'. For reference, see f.e. this page:

A null operand is converted to the
string literal "null".

To avoid this, you should check if one string is null yourself.

盗心人 2024-10-19 10:20:25

这就是 Java 连接的工作原理。
它将 null 对象视为“null”。

请参阅此

This is how Java Concatenation works.
It treats null objects as "null".

Please see this link

无声情话 2024-10-19 10:20:25

这是因为任何你用字符串添加的东西都会默认将其转换为字符串。
即使您尝试将数字添加到字符串中,它也会被转换为字符串。
例子:
“abc”+123=“abc123”
有一种名为 concat 的语法,它只会将字符串添加到字符串,而不添加任何其他内容。
例子 :
如果你输入
"abc".concat(null)
然后它会显示
java.lang.NullPointerException
在 java.lang.String.concat(来源未知)
但如果你输入
"abc".concat("null")
输出将为“abcnull”。

it is because any thing u add it with a string will by default convert it into a string.
and even if you try to add a number to a string it will be converted into string.
example:
"abc"+123="abc123"
there is a syntax called concat which will add only string to string not any thing else.
example :
if u type
"abc".concat(null)
then it will show
java.lang.NullPointerException
at java.lang.String.concat(Unknown Source)
but if u type
"abc".concat("null")
the output will be "abcnull".

迷鸟归林 2024-10-19 10:20:25

让我们编译您的代码并查看字节码:

   // -- Initialization of s1
   5:   ldc             #2; //String abc
   7:   putfield        #3; //Field s1
   // ...

   // -- Initialization of s2
   11:  aconst_null
   12:  putfield        #4; //Field s2
   // ...

   // -- Initialization of s3
   //    create a StringBuilder
   16:  new             #5; //class StringBuilder
   19:  dup
   20:  invokespecial   #6; //Method StringBuilder."<init>"
   // Load s1
   23:  aload_0
   24:  getfield        #3; //Field s1
   // Call StringBuilder.append(String)
   27:  invokevirtual   #7; //Method StringBuilder.append(String)
   30:  aload_0
   // Load s2
   31:  getfield        #4; //Field s2
   // Call StringBuilder.append(String)
   34:  invokevirtual   #7; //Method StringBuilder.append(String)
   // Get content of StringBuilder
   37:  invokevirtual   #8; //Method StringBuilder.toString()
   // Store in s3
   40:  putfield        #9; //Field s3

那么 "null" 如何最终出现在结果中?嗯,这在 StringBuilder.append(String) 的文档中进行了描述:

字符串参数的字符按顺序附加,序列的长度增加了参数的长度。如果 str 为 null,则附加四个字符“null”。

正如 Jon Skeet 指出的那样,这完全符合 Java 语言规范。

Let's compile your code and look at the bytecode:

   // -- Initialization of s1
   5:   ldc             #2; //String abc
   7:   putfield        #3; //Field s1
   // ...

   // -- Initialization of s2
   11:  aconst_null
   12:  putfield        #4; //Field s2
   // ...

   // -- Initialization of s3
   //    create a StringBuilder
   16:  new             #5; //class StringBuilder
   19:  dup
   20:  invokespecial   #6; //Method StringBuilder."<init>"
   // Load s1
   23:  aload_0
   24:  getfield        #3; //Field s1
   // Call StringBuilder.append(String)
   27:  invokevirtual   #7; //Method StringBuilder.append(String)
   30:  aload_0
   // Load s2
   31:  getfield        #4; //Field s2
   // Call StringBuilder.append(String)
   34:  invokevirtual   #7; //Method StringBuilder.append(String)
   // Get content of StringBuilder
   37:  invokevirtual   #8; //Method StringBuilder.toString()
   // Store in s3
   40:  putfield        #9; //Field s3

So how does "null" end up in the result? Well, this is described in the documentation of StringBuilder.append(String):

The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are appended.

As Jon Skeet points out, this is all in accordance with the Java Language Specification.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文