简体   繁体   English

字符串对象的创建及其构造函数

[英]string object creation and its constructor

There are two ways to create String object. 有两种创建String对象的方法。

String str = new String("Java");
String str2 = "Java";

I know in first case constructor will definitely be invoked. 我知道在第一种情况下,肯定会调用构造函数。 But not aware about second one. 但是不知道第二个。 Will constructor be invoked? 构造函数会被调用吗?

String substr = new String(str.substring(2,str.length));  // str is new object
String substr2 = new String(str2.substring(2,str2.length)); //str2 is not with new keyword

want to make sure substr and substr2 are same kind of operation and same behaviour in the heap memory. 想要确保substrsubstr2在堆内存中是相同类型的操作和相同行为。

I know one thing that String.substring() doesn't create new object at all but uses previous char[] object with different offset. 我知道String.substring()根本不创建新对象,而是使用具有不同偏移量的先前char []对象的一件事。

so what happen with substr and substr2 ? 那么substrsubstr2会发生什么呢? Can we relate these things with constructor as offset is generated inside constructor. 我们可以将这些东西与构造函数相关联吗,因为偏移量是在构造函数内部生成的。

From the JLS §3.10.5. 摘自JLS§3.10.5。 String Literals : 字符串文字

A string literal is a reference to an instance of class String (§4.3.1, §4.3.3). 字符串文字是对String类(第4.3.1节,第4.3.3节)的实例的引用。

Moreover, a string literal always refers to the same instance of class String . 而且,字符串文字总是引用类String的相同实例。 This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern . 这是因为使用String.intern方法,对“字符串文字”(或更一般地说,是常量表达式的值(第15.28节)的字符串)进行了“插入”,以便共享唯一的实例。

Thus, "Java" refers to a String object. 因此, "Java"是指String对象。 Furthermore, any string literal consisting of the same charactes would refer to the same String object. 此外,任何由相同字符组成的字符串文字都将引用相同的String对象。 However, how and when this object is constructed is unspecified. 但是,该对象的构造方式和时间尚未指定。

want to make sure substr and substr2 are same kind of operation and same behaviour in the heap memory. 想要确保substrsubstr2在堆内存中是相同类型的操作和相同行为。

Yes, they are exactly the same kind of operation. 是的,它们是完全相同的一种操作。

I know one thing that String.substring() doesn't create new object at all but uses previous char[] object with different offset. 我知道String.substring()根本不创建新对象,而是使用具有不同偏移量的先前char []对象的一件事。

This is unspecified. 未指定。 What you describe is how older versions of Oracle's JDK worked. 您所描述的是Oracle JDK的旧版本如何工作。 Current versions don't do that anymore : substring() now copies the characters. 当前版本不再这样做substring()现在复制字符。 This change was made in Java 7u6. 此更改是在Java 7u6中进行的。

constructor is invoked when any object is created. 创建任何对象时都会调用构造函数。

In case of String str2 = "World"; 如果String str2 = "World"; , jvm will first search for the string "world" in the string pool. ,jvm将首先在字符串池中搜索字符串"world" the constructor will be called only if this literal doesn't exist in pool, otherwise it will return the existing object. 只有在池中不存在此文字时,才会调用构造函数,否则它将返回现有对象。

The constructor should always be invoked. 构造函数应始终被调用。 To find out for yourself debug this application: 要自己找出调试此应用程序:

public static void main(String[] args) {
  String str = new String("Java"); // <-- breakpoint here
  String str2 = "World";
  String str3 = "Java"; // (1)
  String str4 = new String("Java"); // (2)

  System.out.println(str + " " + str2 + " " + str3 + " " + str4);
}

Set the breakpoint on the first line ( String str = new... ) and "Step into" to go into the String() constructor. 在第一行上设置断点( String str = new... ),然后String str = new... “ Step into”进入String()构造函数。 Then "Step out" of the constructor, "Step over" to the next line and "Step into" again. 然后从构造函数中“跳出”,“跳出”到下一行,然后再次“跳入”。 You should be in the String() constructor again. 您应该再次处于String()构造函数中。

1: As for str3 it should come from the pool, ie if (str3 == str) will be true . 1:对于str3来说,它应该来自池,即if (str3 == str)true

2: But str4 will be a new instance, ie if (str4 == str || str4 == str3) will be false . 2:但是str4将是一个新实例,即, if (str4 == str || str4 == str3)false See the String API . 请参阅String API

Let us know what you found :-) 让我们知道您发现了什么:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM