lang包是最基础的包,所以lang包下直接的类是不需要导入的,但是lang包下的子包依然是需要导入的。
如果硬是要导入的话,
导入lang包下直接的类这样写:import java.lang.*
导入lang包子包下的类这样写:import java.lang.reflect.*
接下来是String类:
对于String类,它的性质就是不变性。
虽然(代码段一)最后的输出是"abcd"
,我们会感觉到值“变了”,实际上对于String来说它是没变的。
代码段一:
String str0 = "abc";
str0 = str0 + "d";
这是为什么呢?
因为(代码一)与(代码二)是等同的。
代码一:
String str0 = "abc";
代码二:
final String str0 = "abc";
将这段代码拆分,
前半部分String str0
是引用,开在栈中;
后半部分"abc"
是值,开在方法区的常量池中的StringPool中;
最后在底层得到str0
指向"abc"
。
而str0 = str0 + "d";
这句代码在底层会使得"abc"
产生一个副本同它一模一样,然后用副本来和"d"
拼上,再让str0指向他们("abcd"
)。
此时"abc"
依然在StringPool中,但是str0
指向的已经是"abcd"
了。
(因为(代码段二)及其输出结果,让我对于String底层有这样的理解)
代码段二:
String str0 = "abc";
System.out.println("拼上之前" + str0.hashCode());
System.out.println("拼上之前" + "abc".hashCode());
str0 = str0 + "d";
System.out.println(str0);
System.out.println("拼上之后" + str0.hashCode());
System.out.println("拼上之后" + "abcd".hashCode());
System.out.println("拼上之后" + "abc".hashCode());
System.out.println("拼上之后" + "d".hashCode());
输出结果:
拼上之前96354
拼上之前96354
abcd
拼上之后2987074
拼上之后2987074
拼上之后96354
拼上之后100
(有可能是错的!希望被指正!)
String类对象的初始化可以new也可以不new,比如说:
String str1 = "aaa";
String str2 = new String("aaa");
虽然打印内容的时候都是输出aaa
,但是底层来看是有区别的。
未完待续……