String类
关于String类
-
来自package java.lang;
-
导入的包
import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; import java.lang.annotation.Native; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Formatter; import java.util.Locale; import java.util.Objects; import java.util.Spliterator; import java.util.StringJoiner; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.internal.HotSpotIntrinsicCandidate; import jdk.internal.vm.annotation.Stable;
- 这些包没看明白
但是在注释里面有这些话
Strings are constant; their values cannot be changed after they are created.
字符串是常量;它们的值在它们被创建后无法修改
Because String objects are immutable they can be shared
因为字符串对象是不可变的,所以可以共享它们。
在后面的源码中
String str = "abc";
is equivalent to://相当于
char data[] = {'a', 'b', 'c'};
String str = new String(data);
Here are some more examples of how strings can be used://下面是关于字符串的更多示例
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
//在测试后知道了substring();方法的用处,即
public String substring(int beginIndex, int endIndex) {//传入字符串的下标(起始和结束)
int length = length();//字符串长度
checkBoundsBeginEnd(beginIndex, endIndex, length);
int subLen = endIndex - beginIndex;
if (beginIndex == 0 && endIndex == length) {
return this;//这里的this指是原字符串对象的引用
}
return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
: StringUTF16.newString(value, beginIndex, subLen);
}
//关于checkBoundsBeginEnd,从下面的代码可以看出来吗,这个方法是检验传入的下标是否符合要求的即是否在字符串长度内的
static void checkBoundsBeginEnd(int begin, int end, int length) {
if (begin < 0 || begin > end || end > length) {
throw new StringIndexOutOfBoundsException(
"begin " + begin + ", end " + end + ", length " + length);
}
}
//关于isLatin1()
private boolean isLatin1() {
return COMPACT_STRINGS && coder == LATIN1;
}
@Native static final byte LATIN1 = 0;
static final boolean COMPACT_STRINGS;
static {
COMPACT_STRINGS = true;
}
//关于newString()
public static String newString(byte[] val, int index, int len) {
return new String(Arrays.copyOfRange(val, index, index + len),
LATIN1);
}
- 先打住!
看看substring();方法输出的结果
//---------------测试代码
public class Test02 {
public static void main(String[] args) {
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
System.out.println(c);
String d = cde.substring(1, 2);
System.out.println(d);
}
}
//---------------结果
abc
abccde
c//即"abc"从2开始截至3的字符串内容截至的3是不包括的
d//即"cde"从1开始截至2的字符串内容,当然不包括2
@Stable
private final byte[] value;
private final byte coder;
private int hash; // Default to 0 //哈希值默认为0
/*说明String中有char数组,并且被final修饰,只能赋值一次!*/
//String内的构造方法
//无参
public String() {
this.value = "".value;
this.coder = "".coder;
}
//有参,String为参数的构造方法
@HotSpotIntrinsicCandidate
public String(String original) {
this.value = original.value;
this.coder = original.coder;
this.hash = original.hash;
}
//char数组为参数的构造方法
public String(char value[]) {
this(value, 0, value.length, null);
}
//其实还有两个构造方法
- 于是乎就有了两个常见的String类型创建方式
public class Test02 {
public static void main(String[] args) {
String str1 = "str";
String str2 = new String("str");
}
}
- 在上面的源码注释和代码中我们知道,字符串常量是在类加载的时候就已经存在的,且存在于方法区内存中,存在的区域被称为,字符串常量池。
//接下来对上述代码测试
public class Test02 {
public static void main(String[] args) {
String str1 = "str";
String str2 = new String("str");
System.out.println(str1 == str2);
System.out.println(str1.hashCode() == str2.hashCode());
}
}
/*
输出结果
false
true
*/
未完!