这变得显而易见,但如果你问我,我不知道为什么我可以只使用 String s = "ABC";
或 Integer i = 1;
为什么我们可以通过字面量来初始化String、Integer等?
最佳答案
好吧,因为没有其他人知道,所以我会尝试一下。
Why I can use just
String s = "ABC";
您可以这样做,因为 "ABC"
被定义为 String
语言的文字,并且因为文字的类型是分配给 String
的正确类型。引用。对此进行扩展(对格式表示歉意):
Java Language Specification, section 3.10定义了 6 种不同的文字:
- 整数常量
- 浮点文字
- boolean 文字
- 字 rune 字
- 字符串文字
- 空文字
其中 StringLiteral 是:
-
"
{StringCharacter}"
并且StringCharacter是:
- InputCharacter,但不是
"
或\
- 转义序列
稍后,在 JLS 第 3.10.5 节中:
A string literal is a reference to an instance of class
String
.
因此,从类型检查的角度来看,该分配是有意义的,因为 "ABC"
被定义为代表 String
对象,同时跳过通常的 new <constructor>(...)
符号。
字符串被认为在编程中使用得如此普遍,以至于语言设计者选择在语言语法中特殊对待它们。 Java 并不是执行此操作的唯一语言 - 您可以看到 String
的相同特殊处理。许多其他语言中的文字。
Integer i = 1;
实际上,您只能从 Java 5 开始执行此操作,当时引入了自动装箱。其工作原理是因为编译器将文字赋值转换为幕后的方法调用,从而允许从基本类型到其包装器的透明转换。因此,这段代码:
class A {
Integer i = 1;
int i2 = i;
}
在编译为字节码之前处理此代码:
class A {
A() {
super();
}
Integer i = Integer.valueOf(1);
int i2 = i.intValue();
}
您可以通过传递 -XD-printflat
来验证这一点标记为javac
编译之前。您还必须使用 -d <path>
标志指定输出路径。这显示了编译器在将 Java 源代码转换为 Java 字节码之前对源代码的处理方式。所以这显示了自动装箱、通用删除等的结果。
您看到的那些方法调用是您可以“按文字初始化 Integer
”的原因。从技术上讲,您并没有这样做,因为初始化被编译为方法调用,但自动装箱给人一种错觉,即文字初始化正在发生。如果您使用 Java 5 之前的编译器来尝试此操作,您会收到错误。您可以通过运行以下命令来测试:
javac -source 1.4 A.java
在我的计算机上,这会给出以下输出(减去一些不相关的警告):
A.java:2: error: incompatible types: int cannot be converted to Integer
Integer i = 1;
^
A.java:3: error: incompatible types: Integer cannot be converted to int
int i2 = i;
^
2 errors
关于java - 为什么我们可以通过字面量来初始化String、Integer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24607977/