String属于java.lang包。
String是被final修饰的类,所以说String是不能继承的。
String中实现了下列接口:
java.io.Serializable
Comparable<String>
CharSequence
String 包含如下属性:
无参:
String str = "abc";
这个在创建的时候是,先在栈中查找有没有值为"abc"的字符串,如果有,将它的栈地址给str;如果没有,将"abc"加载到栈中,然后再将它在栈中的地址给str.
同理,如果此时还有一个 String str1 = "abc";那么,经过查找后,在栈中找到了值"abc"就不用再加载值了,直接将地址给str1就像,此时它们指向的是同一个地址。
有参:
String str = new String("abc");
这个有两个对象,第一个是new String("abc"),这个是在堆中完成的,第二个是String str = ,这个是在栈中完成的,第一个结束后会将所创建的对象的地址赋给在栈中的第二个对象。并且,如果还有一个 String str1 = new String("abc");那么,它也不会跟上一个相同,同样的流程它仍然会再走一次。
所以在试用的时候,尽量不要用new String,因为同样的对象它会不停的创建,这不但消耗了内存而且还降低了效率。
String是被final修饰的类,所以说String是不能继承的。
String中实现了下列接口:
java.io.Serializable
Comparable<String>
CharSequence
String 包含如下属性:
/** The value is used for character storage. */
private final char value[];
这才是String真正存储数据的地方,也就是说平时我们用到的String值其实是一个char[].
/** The offset is the first index of the storage that is used. */
private final int offset;
记录数据位置
/** The count is the number of characters in the String. */
private final int count;
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
String有多种构造器,主要看一下我们最常用的:
无参构造器
/**
* Initializes a newly created {@code String} object so that it represents
* an empty character sequence. Note that use of this constructor is
* unnecessary since Strings are immutable.
*/
public String() {
this.offset = 0;
this.count = 0;
this.value = new char[0];
}
有参构造器:
/**
* Initializes a newly created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* @param original
* A {@code String}
*/
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
无参与有参在内存中有着比较大的区别;
无参:
String str = "abc";
这个在创建的时候是,先在栈中查找有没有值为"abc"的字符串,如果有,将它的栈地址给str;如果没有,将"abc"加载到栈中,然后再将它在栈中的地址给str.
同理,如果此时还有一个 String str1 = "abc";那么,经过查找后,在栈中找到了值"abc"就不用再加载值了,直接将地址给str1就像,此时它们指向的是同一个地址。
有参:
String str = new String("abc");
这个有两个对象,第一个是new String("abc"),这个是在堆中完成的,第二个是String str = ,这个是在栈中完成的,第一个结束后会将所创建的对象的地址赋给在栈中的第二个对象。并且,如果还有一个 String str1 = new String("abc");那么,它也不会跟上一个相同,同样的流程它仍然会再走一次。
所以在试用的时候,尽量不要用new String,因为同样的对象它会不停的创建,这不但消耗了内存而且还降低了效率。