为什么我们可以按字面值初始化String,Integer?

时间:2014-07-07 10:03:47

标签: java string integer initialization

这很明显,但如果你问我,我不知道为什么我只能使用String s = "ABC";Integer i = 1;

为什么我们可以用文字初始化String,Integer等?

1 个答案:

答案 0 :(得分:2)

好的,因为没有其他人有位,我会捅它。

  

为什么我只能使用String s = "ABC";

您可以这样做,因为"ABC"被语言定义为String字面值,并且因为文字的类型是要分配给String引用的正确类型。为了扩展这一点(格式化道歉):

Java Language Specification, section 3.10定义了6个不同的文字:

  • IntegerLiteral
  • FloatingPointLiteral
  • BooleanLiteral
  • 字符文字
  • 串文字
  • NullLiteral

StringLiteral 的位置为:

  • " {StringCharacter} "

StringCharacter 是:

  • InputCharacter 但不是"\
  • EscapeSequence

稍后,在JLS第3.10.5节中:

  

字符串文字是对类String的实例的引用。

因此,从类型检查的角度来看,赋值是有意义的,因为"ABC"被定义为表示String对象,同时跳过通常的new <constructor>(...)表示法。

字符串被认为在编程中如此常用,语言设计者选择在语言语法中特别对待它们。 Java并不是唯一可以做到这一点的语言 - 你可以在许多其他语言中看到对String文字的同样特殊处理。


  

整数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字节码之前立即处理源代码的内容。所以这显示了自动装箱,通用擦除等的结果。

您看到的那些方法调用是您可以通过文字&#34;初始化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