第一个代码如下所示:
String s = "hello";
第二个代码如下所示:
String s = new String("hello");
问题:这两个代码是否调用String(char[])
的相同构造函数?
String
有一个private final field char value[]
。为什么设置为final
字段?这样我们每次调用时都会创建一个新的String
来改变string的值。将字段char value[]
设置为final
的目的是什么?
答案 0 :(得分:4)
问题:两个代码是否调用了相同的String构造函数(char [])?
不,绝对没有。
第一种形式将字符串内容直接烘焙到字节码中,然后使用ldc
(加载常量)指令从字符串池中加载它。
重要的是,每个出现的字符串常量"你好"将引用相同的对象。
将其与您的第二个表单进行比较,每次执行语句时都会创建一个新字符串。
至于最终领域的细节:无论如何它都是一个私人领域,所以你不应该关心。但它是最终的,因为Java字符串是不可变的 - 没有理由为什么你希望改变它的价值。 (本身并不足以强制实现不变性;任何有权访问char[]
的人都可以修改数组的内容。)
答案 1 :(得分:2)
我确信这在其他地方得到了回答,但我懒得查一查 -
在Java中声明“字符串文字”时,在包含类的类加载期间,该文字将被分配为Java String对象。 (顺便说一句,字符串是“实习”。)
因此,当您说String s = "Hello";
时,您只是将对现有String对象的引用分配给变量s
,无论您在程序中执行该分配的频率如何,不要再创建String的实例。
new String
始终创建一个新的String对象。
String对象中的char[]
数组是存储String的实际值的位置。
(请注意,String是不可变的 - 一旦创建就无法更改它。当您将新值指定为现有String
引用时,您将分配 new 对象,而不是更新现有的String
对象。)
答案 2 :(得分:0)
Question: Are the two codes invoking the same constructor of String(char[])?
您假设“hello”是char [],但它不是,它是一个String。您可以调用String方法,例如"hello".charAt(0)
所以:
String s = "hello";
没有调用构造函数。 “hello”已经是一个String,并被赋值给变量s
。
并在
String s = new String("hello");
调用构造函数String(String)
。
对于你的第二个问题:value
是最终的,因为在Java中,字符串是不可变的。
答案 3 :(得分:0)
String s = "hello";
的引用
引用有关String litterals的引用JLS部分:
(..)字符串文字总是引用类String的相同实例。这是因为字符串文字 - 或者更常见的是作为常量表达式(§15.28)的值的字符串 - 被“实例化”以便使用String.intern方法共享唯一实例。(..)
String s = new String("hello");
现在,这是通过调用String constructor with a single String argument创建的String对象的引用。
Are the two codes invoking the same constructor of String(char[])?
不,there isn't a call within this constructor to the overloaded constructor you are referring to。
String has a private final field char value[]. Why is it set to a final field?
因此,一旦构造函数设置它就无法更改。这是String作为immutable object所需的步骤之一。