Java字符串的细微差别

Java字符串的细微差别,java,string,Java,String,任何人都可以解释这种行为的原因吗?此代码: class Test { public static void main() { String s1 = null + null; //shows compile time error String s1 = null; String s2 = s1 + null; //runs fine } } 尝试对两个null执行加法操作,该操作无效 在这里: String s1 = null

任何人都可以解释这种行为的原因吗?

此代码:

class Test {
    public static void main() {
        String s1 = null + null; //shows compile time error
        String s1 = null;
        String s2 = s1 + null;   //runs fine
    }
}
尝试对两个
null
执行加法操作,该操作无效

在这里:

String s1 = null + null;
您已将
null
分配给
s1
。然后执行
s1
null
的串联。
s1
的类型是
String
,因此
s1+null
中的
null
将根据字符串转换规则转换为
“null”
字符串,如中所示

如果引用为null,则将其转换为字符串
“null”
(四个 ASCII字符
n、u、l、l

否则,转换就像通过调用
toString
引用对象的方法,不带参数;但是如果 调用
toString
方法的结果是
null
,然后字符串
“null”
而是使用


和串联将作为-
s1+“null”执行

仅当一个(或两个)操作数的类型为
字符串时,
+
运算符作为
字符串
串联才适用

如果
+
运算符的任一操作数的类型为
字符串
,则该操作为字符串串联

操作数具有
null
类型,即非
String
,因此不会发生字符串串联。然后,Java认为您正在做一个加法,它对
null
类型也不起作用

s2
具有类型
String
,即使它引用的是
null
,也可以进行字符串连接。

来自:

Java语言为字符串提供了特殊支持 连接运算符(+),用于将其他对象转换为 串。字符串连接是通过 StringBuilder(或StringBuffer)类及其
append
方法


因此,由于
StringBuffer.append(Object Object)
接受
Object
(包括
null
)作为参数,因此至少左操作数不能为null。

在以下情况下,您对两个
null
执行操作,并且
+
操作没有为两个
null
定义

String s2 = s1 + null;   //runs fine
String s1 = null + null;
在本例中,您将执行
字符串
null
的串联

String s2 = s1 + null;   //runs fine
String s1 = null + null;
另一个有趣的例子是,

String s2 = s1 + null;

当您将
string
强制转换为
null
时,将产生“nullnull”字符串,并再次执行连接。因此,首先
null
将被视为
String

基本上这是因为您处理的是文本,因此编译器试图对这些文本值执行操作。它发生在编译时,与两个空值无关


您遇到的编译器错误相当于一个异常——编译器不知道如何处理它,因此它会出错,并给类型一个解释,说明它不起作用。

一个可能会引导您的问题:您会将表达式“null+null”分配给什么类型?为什么?如果“null”,第一个可能会起作用总是只指缺少字符串对象,但事实上,它表示没有任何对象,因此“+”没有对象类型来指导对“+”的特定含义的选择。空值是显式的,因此空值+空值只是编译时的一种低挂果检查,但变量在运行时可能变为空值。在第二种情况下,编译器必须检查s1在s2赋值之前是否为null,以便将其踢出。@Mike-如果null被设置为null的字符串变量替换,则编译器将尝试调用字符串ops来处理它。但是,将失败,因为
concat
将以null调用。另外:此代码无效,因为
s1
声明了两次。可能使用不同的范围,将两个例子放在不同的块中?@ BheshGurung,在这种情况下,关联性并不是真正相关的,因为只有一个操作符存在,但是请考虑表达式<代码> A+B+C 。因为
+
是左关联的,所以表达式被解析为
(a+b)+c
。如果它是正确关联的,表达式将被解析为
a+(b+c)
。(运算符也可能是非关联的,在这种情况下,表达式可能是语法错误或具有某种特殊含义,具体取决于语法定义。)它不会转换为字符串
“null”
,对吗?我以为它只是一个空指针。实际上,我有点惊讶于它的工作原理。唯一的说明是,“如果只有一个操作数表达式是字符串类型,则在运行时对另一个操作数执行字符串转换(§5.1.11)以生成字符串。”没有提及对两个操作数应用字符串转换的任何情况,这是这项工作所必需的。@Stendika:它被转换为
s1+null
加法,而不是
s1=null
赋值。@user2357112并且不是
s1
类型的
String
,在
s1+null
中?直接使用时,
null
没有类型,但是当它被分配给
String s1
时,操作员将看到
s1
的类型,而不是它是否为
null
。+1用于引用StringBuffer-我认为这是公认答案中的一个重要遗漏。但是,您的答案总体上不太完整。是的,因为大多数概念已经解释过了,所以您的答案不太完整。我认为您没有解释StringBuffer接受null是如何回答这个问题的,但是-这个答案应该显示编译器将字符串串联转换为什么,为了弄清楚为什么两个空值都不会导致
String abcd = (String) null + null;