【问题标题】:How String s ="sometext" works?String s ="sometext" 如何工作?
【发布时间】:2017-02-02 13:12:49
【问题描述】:

在面向对象的语言中,新对象的创建是通过使用 new 关键字(因为 java 中的内存分配是动态完成的)。

即使 String 是一个类,如何在没有 new 关键字的情况下创建它的对象?

即使它使用字符串池,我也无法清楚地理解它: “可以创建一个用户定义的类,我们可以像String一样直接初始化变量”

【问题讨论】:

  • 不,不是。编译器以一种特殊的方式处理String literals,这是其他对象无法做到的(自动装箱的原语除外)。
  • 如果你真的想要做这样的事情,你可以切换到 Scala(另一种 JVM 语言),并创建一个隐式类,它会自动将某些上下文中的字符串转换为班级。不过,我会质疑为什么这是必要的。
  • @Kayaman (nit-picking) 也可以用于 Lambdas... [:-)
  • @CarlosHeuberger 没错,我本来打算“不可能”,但后来我开始思考,好吧,思考让我以前遇到过麻烦。

标签: java string oop


【解决方案1】:

编译器和 JVM 中内置了使您能够使用字符串文字创建 String 对象的机制。它不适用于用户定义类型的对象。

当你第一次写作时

String s = "sometext";

编译器会发出两件事:

  • 一个带有"sometext"constant pool 条目,并且
  • s 设置为引用常量表中的条目的指令。

如果你写

String t = "sometext";

在同一个类中,编译器将为"sometext" 重用现有常量,而不是创建一个新常量。

在运行时,JVM 为常量表中的每个条目创建一个新的String 对象,并让您的程序访问它们。本质上,JVM 代表您的程序调用new,并将其交给一个现成的对象。

当您使用自动装箱创建原始包装器的实例时,类似的系统正在发挥作用。然而,共同点是它需要编译器的支持,并且不适用于用户定义的类型。

【讨论】:

  • @ΦXocę웃Пepeúpaツ 这取决于 JVM。 “同一类”是最低要求,但other JVMs 可以更积极地共享字符串。
【解决方案2】:

在 Java 中,字符串是不可变的,并且可以选择池化(“interned”)。

"sometext" 只是来自静态池的String 的一个实例。

您不能创建用户定义的字符串,因为 java.lang.String 是一个 final 类,这正是因为不可变性(您可以通过将它们指向单个实例来共享重复项)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    相关资源
    最近更新 更多