2

为什么是java.lang.String唯一存在两种创建方式的类:

1)用“ new”关键字的正常方式。

String s = new String("abc");

2)使用String文字(仅适用于String类)

String s = "abc";

那么为什么有String文字而没有其他任何类的文字呢?

4

10 回答 10

10

简短的回答,因为语言设计者喜欢它。

我猜 String 是一个非常常见的类,以至于他们例外。我敢肯定还有其他一些类似的例外,(请参阅 Tom Hawtins 评论)

于 2009-09-10T12:08:01.470 回答
5

撇开自动装箱(这不包括 IMO - 文字用于原始类型而不是类;只是对包装类的隐式转换),String(String)构造函数实际上很有用。它需要一个字符数据的副本,这意味着如果原始字符串很小但有很大的 backing char[],则新字符串独立于它。

例如,如果您正在从文件中读取短行,这可能很重要。

至于为什么会有字符串文字:因为它们很有用。你会拥有什么?您是否要强制开发人员使用:

String x = new String(new char[] { 'h', 'e', 'l', 'l', 'o' });

同时不去实习?

您还想要什么其他类的文字?可以说,地图和列表的文字会很有用——我不记得它们是否出现在 Java 7 中。您可以将数组初始值设定项视为“有点像文字”,因为它是对象初始化的简写。

于 2009-09-10T12:13:41.140 回答
3

我想是因为 String 是一种基本数据类型,因此他们将其视为与原语相同的级别。

顺便提一句,

new String("abc");

实际上创建了 2 个字符串:

  1. 实习生,你失去了参考
  2. 具有相同内容的新实例

就个人而言,我从来没有发现需要使用 String 的构造函数。

于 2009-09-10T12:15:38.250 回答
2

字符串虽然是一个普通的类,但代表了编程的基本元素之一(其他是数字和布尔值)。因此,Java 从一开始就将 String 对象视为半原始变量,并允许这样做。

后来,当自动装箱成为标准编译器的一部分时,您也可以用这种方式构建数字包装对象,即

Integer i = 123;

正如 Tom Hawtin-tackline 在对问题的评论中提到的那样。

于 2009-09-10T12:11:47.697 回答
1

当然,还有所有原始数字类型的文字,以及布尔值 true 和 false 以及字符。我想您可以回答,在您的问题中,您从技术上说“没有任何其他的文字”。好的。我认为有人指出“null”是一个文字对象,所以你的陈述在技术上是不准确的,但我认为这是唯一的另一个例子。

但是,下一个明显的问题是,您希望其他哪些类具有文字?如果您正在设计语言,那么 BufferedReader 文字会是什么样子?还是 ResultSet 文字?还是一个 JCheckBox?

理论上,您可以说,例如,“文件文字”是包含在某些特殊分隔符中的文件名,例如“$/home/bob/myfile.txt$”。但是有人可能会说,JButton 怎么样,我们不能用按钮的文本和它触发的 ActionListener 和适当的分隔符(如“%Submit,SubmitListener%”)来为它创建一个文字。那么套接字呢,我们不能将主机名放在一些特殊的分隔符中,等等。我认为很明显我们很快就会用完标点符号来用作分隔符。所以我们最终不得不写一些文本来识别我们正在谈论哪个类,比如说 File("/home/bob/myfile.txt") 或 Socket("www.example.com",631 )。但这看起来非常像构造函数,我们

可以纯粹由值的性质(例如,所有数字构成数字文字)或标点符号表示的“事物”的数量受到可以合理地安装在键盘上的标点符号数量的限制。您是否想要一个带有 600 个特殊图标的键盘来处理您可能想要谈论的所有不同类型的事情?单词更容易,更灵活。

字符串是如此常用,替代方案会非常尴尬,因此将其设为特殊情况是有意义的。

于 2009-09-10T13:25:52.837 回答
1

具有字面量的对象类型是Stringsnull类字面量

也可以对数组使用初始化器,如果用作初始化器,原始文字也可以用于创建对象,这符合简单语法中的“两种创建方式”而不是真正的文字(它们只能用于初始化一个值而不是而不是在所有可能出现对象表达式的地方)。

如果使用序列化和反射等其他技术,也可以打破“两种创建方式”。

于 2009-09-10T12:22:23.960 回答
1

Java 7 旨在提供通过文字来初始化集合的能力,就像数组文字一样:

于 2009-09-10T15:58:34.973 回答
0

最后我检查了:

Integer wInt = 1;

工作得很好。

于 2009-09-10T12:08:45.663 回答
0

后一种创建形式还涉及字符串实习。也就是说,如果你有代码:

String s = "abc";
String t = "abc";

编译器将对此进行优化,您将获得对同一个 String 对象的两个引用。(s == t 将是真的)。

字符串实习也适用于字符串表达式。

于 2009-09-10T12:17:16.950 回答
0

字符串文字是一种便捷的捷径,具有良好的优先级(在 C 中)和语法。如果 Java 设计者想要吸引 C++ 程序员,那么字符串文字就必须存在。幸运的是,Java 中的字符串处理比 C++ 中的要好得多。

没有其他标准对象具有事实上的语法 - 你将如何编写映射文字?

于 2009-09-10T13:35:54.090 回答