Java 你怎么能打印:“你怎么能打印?”;“真的”+;null但不是:true+;无效的
汇编如下:Java 你怎么能打印:“你怎么能打印?”;“真的”+;null但不是:true+;无效的,java,null,Java,Null,汇编如下: System.out.println("true" + null); 我假设这是因为字符串的存在,也会将“null”转换为字符串 然而,由于这是可行的: System.out.println(true); 下面的代码似乎也可以编译,因为显然“true”函数是字符串 System.out.println(true + null); 但是,它不编译 有人能解释一下吗?操作符对数字(int,float,double)和字符串起作用,但在这种情况下,你用它来添加一个布尔值和一个对象(即
System.out.println("true" + null);
我假设这是因为字符串的存在,也会将“null”转换为字符串
然而,由于这是可行的:
System.out.println(true);
下面的代码似乎也可以编译,因为显然“true”函数是字符串
System.out.println(true + null);
但是,它不编译
有人能解释一下吗?操作符对数字(
int
,float
,double
)和字符串起作用,但在这种情况下,你用它来添加一个布尔值和一个对象(即null
),这是错误的
但是,既然这样行得通,
System.out.println(true);
下面的代码似乎也可以编译,因为显然“true”函数是字符串
System.out.println(true + null);
System.out.println(真+空)
前者可以工作,因为System.out.println(boolean)
将布尔值
转换为字符串
。后者不会
研究为什么null
转换为“null”
,而不产生任何问题,因为:
null.toString()
由于明显的原因无法编译
StringBuilder.append(null)
不编译
String.valueOf(null)
编译,但在运行时抛出NullPointerException
看起来编译器不是直接使用null
,而是首先创建一个对象o
,然后String s
变量并将null
赋值给它,然后使用String.valueOf(s)
。所以,这个代码:
System.out.println("true" + null);
事实上
System.out.println(new StringBuilder().append("true").append((Object)null).toString());
如果我们做相反的事情:
System.out.println(null + "true");
这将成为:
System.out.println(new StringBuilder().append((Object)null).append("true").toString());
为了证明这既不是魔法也不是黑巫术,我只编写了一个简单的代码来复制这种情况:
public class TestNullString {
public static void main(String[] args) {
nullPlusString();
stringPlusNull();
}
public static void nullPlusString() {
System.out.println(null + "foo");
}
public static void stringPlusNull() {
System.out.println("foo" + null);
}
}
使用java TestNullString.java
编译该类,然后使用javap-c TestNullString.class
反编译该类,该类生成了(由反编译器本身自动生成的注释,而不是我的注释):
和String#valueOf(Object)
实现:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
这完全说明了为什么null
最终会变成“null”
这里还做了另一个解释:操作符对数字(int
,float
,double
)和String
)起作用,但在本例中,您使用它来添加一个boolean
和一个对象
(即null
),这是错误的
但是,既然这样行得通,
System.out.println(true);
下面的代码似乎也可以编译,因为显然“true”函数是字符串
System.out.println(true + null);
System.out.println(真+空)
前者可以工作,因为System.out.println(boolean)
将布尔值
转换为字符串
。后者不会
研究为什么null
转换为“null”
,而不产生任何问题,因为:
null.toString()
由于明显的原因无法编译
StringBuilder.append(null)
不编译
String.valueOf(null)
编译,但在运行时抛出NullPointerException
看起来编译器不是直接使用null
,而是首先创建一个对象o
,然后String s
变量并将null
赋值给它,然后使用String.valueOf(s)
。所以,这个代码:
System.out.println("true" + null);
事实上
System.out.println(new StringBuilder().append("true").append((Object)null).toString());
如果我们做相反的事情:
System.out.println(null + "true");
这将成为:
System.out.println(new StringBuilder().append((Object)null).append("true").toString());
为了证明这既不是魔法也不是黑巫术,我只编写了一个简单的代码来复制这种情况:
public class TestNullString {
public static void main(String[] args) {
nullPlusString();
stringPlusNull();
}
public static void nullPlusString() {
System.out.println(null + "foo");
}
public static void stringPlusNull() {
System.out.println("foo" + null);
}
}
使用java TestNullString.java
编译该类,然后使用javap-c TestNullString.class
反编译该类,该类生成了(由反编译器本身自动生成的注释,而不是我的注释):
和String#valueOf(Object)
实现:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
这完全说明了为什么null
最终会变成“null”
这里还做了另一个解释:它没有编译,因为语句操作数true
和null
不适用于+
操作。适用夫妇为:
- 所有数字类型,包括包装器。例如:
新整数(1)+新整数(2)
- 字符串+对象(因为为每个对象定义了
.toString()
方法)。例如:“newObject().toString()+”cde“
- 字符串+null。例如:
“abc”+null
注释(感谢@Luiggi和@Sotirios):
- 结果
String.valueOf(null)
将不会作为可能的操作数工作,因为它将抛出NullPointerException
- …但是
String.valueOf((Object)null)
将返回字符串值“null”
它无法编译,因为语句操作数true
和null
不适用于+
操作。适用的对数为:
- 所有数字类型,包括包装器。例如:
新整数(1)+新整数(2)
- 字符串+对象(因为为每个对象定义了
.toString()
方法)。例如:“newObject().toString()+”cde“
”李>
- 字符串+null。例如:
“abc”+null
注释(感谢@Luiggi和@Sotirios):
- 结果
String.valueOf(null)
将不会作为可能的操作数工作,因为它将抛出NullPointerException
- …但是
String.valueOf((Object)null)
将返回字符串值“null”
这种假设是错误的。因为你打了电话,所以它起作用了
public void println(boolean x)
但是,
true + null
在Java中不是有效语句,因为您不能添加或追加布尔值和对象
这个