java 基础知识,查缺补漏之
String
字符串
JDK 1.8
以前String
保存的是字符数组JDK1.9
以后String
保存的是字节数组- 请解释
String
比较中“==”
与equals()
区别?。
“==”
:进行的是数值比较,如果用于对象比较.上比较的是两个内存的地址数值
equals()
:是类所提供的一个比较方法,可以直接进行字符串内容的判断。 - 任何使用
""
定义的字符串常量实际上描述的都是一个String
类的匿名对象 - 使用
equals()
进行字符串比较时,字符串常量写在前面,如果写在后面,可能造成空指向异常
public class Hello {
public static void main(String[] args) {
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
}
}
String类两种实例化方式区别
- 直接赋值(推荐):只会产生一个实例化对象,并且可以自动保存到对象池之中,以实现该字符串实例的重用
- 构造方法:会产生两个实例化对象,并且不会自动入池,无法实现对象重用,但是可以利用
intern()
方法手工入池
public class Hello {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
// 两个对象所指向的堆内存是同一个
System.out.println(str1 == str2); // true
// 实例化对象时,如果`String`对象池中存在,就不会再开辟堆内存,
// 栈内存指向已存在的堆内存,所以地址比较的值为true(指向同一块堆内存)
}
}
- 在采用直接赋值的处理过程之中,对于字符串而言可以实现池数据的自动保存,这样如果再有相同数据定义时可以减少对象的产生,以提升操作性能。
public class Hello {
public static void main(String[] args) {
String str1 = "hello";
// 手工入池
String str2 = new String("hello").intern();
System.out.println(str1 == str2); // true
}
}
- 使用构造方法实例化
String
对象,会开辟两块堆内存空间,只会使用一块,而另外一个由于字符串常量所定义的匿名对象将成为垃圾空间。
String 对象常量池
对象池的主要目的是实现数据的共享处理。以String
对象池为例,里面的内容主要就是为了重用,而重用实际上是共享设计。
但是在Java之中对象(常量)池实际上可以分为两种
- 静态常量池:指的是程序(
*.class
)在加载的时候会自动将此程序之中保存的字符串、普通的常量、类和方法的信息等等,全部进行分配 - 运行时常量池:当一个程序(
* .class
) 加载之后,里面可能有一些变量,这个时候提供的常量池。
public class Hello {
public static void main(String[] args) {
String str1 = "How are you!";
String str2 = "How " + "are" + " you!";
// 静态常量池
System.out.println(str1 == str2); // true
String str3 = "are";
String str4 = "How " + str3 + " you!";
// 动态常量池
System.out.println(str3 == str4); // false
}
}
参考链接:
- 国内最新JAVA10培训课堂 [by 魔乐科技]
- String 类常用方法