在Java中,为什么我们可以像使用String一样使用String类?

Ale*_*roF 24 java string class

在Java中我们通常会这样做:

Class myObject = new Class();
Run Code Online (Sandbox Code Playgroud)

因为new关键字返回一个地址.

但为什么我们这样做呢?:

String myString = "Hello";
Run Code Online (Sandbox Code Playgroud)

仿佛String是一个原始人?

我向老师问了这个问题,他回答说这是因为引号中的内容相当于一个地址,但他不确定.你确定吗?

"Hello"是否存储在String类的实例变量中?

T.J*_*der 16

......仿佛String是一个原始人?

正如Jon在评论中指出的那样,"有一个字面形式"!="是一种原始类型." :-)字符串在Java中有一个文字形式,因为规范为它们定义了一个.String仍然是一种对象类型.

有些语言还有其他对象类型也有文字形式(例如,JavaScript有正则表达式,数组和非数组对象的文字形式[字符串的字面形式实际上定义了它所谓的字符串原语而不是字符串对象- JavaScript有原始字符串和对象版本的字符串]).我认为字符串是Java中唯一的字符串(除了null,它是"无对象"的文字),虽然当然有数组初始值设定项,它们文字相似但不完全相同.

  • 现在我有了第二个想法:**Class Literals**.从Java 1.1开始,有类文字.`Class <?> cl = Long.class;`这些绝对合格,即使JLS作者忘记在[Literals部分]中命名它们(https://docs.oracle.com/javase/specs/jls/se8/html /jls-3.html#jls-3.10).他们在[他们自己的部分](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.8.2)... (2认同)

Gho*_*ica 13

您可以使用文字表达式这一事实并不意味着表达式会产生基本类型!这只是对你的误解.

你看:

 Integer[] numbers = { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)

也是一个文字(好吧,"几乎";因为你只能将它用于这种类型的数组init语句); 但它不是原始类型!

并问问你问题的原因:机会是 - 只是为了方便.当Java被创建时,它意味着比那些时代的C和C++"更好".并猜测:处理字符串是非常烦人的,并且在这些语言中容易出错.

从这个意义上讲:引入字符串文字可以被视为区分Java与竞争对手的独特卖点!


Ked*_*ade 8

其他答案都很不错.一些具体要点:

我向老师问了这个问题,他回答说这是因为引号中的内容相当于一个地址,但他不确定.你确定吗?

是.他是对的.正如其他人所指出的那样,字符串文字,即包含在一对"s"中的有效Unicode字符序列被Java语言规范识别.当Java编译器(javac程序"Hello")在Java源代码中遇到这样的文字(例如)时文件,它从字面上理解它并将它放在编译的类文件中的特定部分.这一部分称为运行时常量池.然后创建一个特殊的指令调用ldc它放在类文件中,其中初始化的编译代码是例如,main以下Java源代码中的方法体:

public class StringAsPrimitive {
    public static void main(String[] args) {
        String s = "Hello";
    }
}
Run Code Online (Sandbox Code Playgroud)

被编译为:

     0: ldc           #2                  // String Hello
     2: astore_1
     3: return
Run Code Online (Sandbox Code Playgroud)

(这里没有魔法.只需使用javac程序编译代码并使用程序查看类文件javap.您甚至可以使用十六进制查看器查看.class文件的内容,您将看到字符串Hello 字面意思).

当您要求程序运行此类文件时,JVM会解释此代码.java

此处ldc记录了JVM 的指令.这就是JVM在解释哪个是对文本字符串存储在计算机内存(RAM)中的实际位置的引用时所做的事情:#2"Hello"

否则,如果运行时常量池条目是对表示字符串文字(第5.1节)的类String实例的引用,则对该实例的引用值将被推送到操作数堆栈.

所以,你的老师所说的是正确的,尽管我们并没有这么说.在Java中,有两种类型:基元和引用.因此,更合适的做法是String字面值是一个引用(而不是地址).

"Hello"是否存储在String类的实例变量中?

不可以.初始化为String文字的String变量可以是任何东西,一个static或一个类变量,一个实例变量或一个局部变量(我上面的代码).它存储在类文件中:StringAsPrimitive.class以后它可用于特定内存位置的JVM.当JVM 加载类时会发生这种情况.