简述String类
在开始之前,我们先来几个问题:
String a = "abc";
String b = "abc";
System.out.println(a==b) // 结果是true还是false?
String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1==s2)
// 结果是true还是false? 这个过程中一共创建了几个对象?
String类定义
- Java JDK中内置的一个类:java.lang.String
- Java中String表示字符串类型,属于引用类型,继承Object类
- Java中使用双引号括起来的都是String对象
- 在Java中规定,双引号括起来的字符串,是不可变的!
- 在Java中双引号括起来的字符串,都是直接存放在方法区中的“字符串常量池”中(为了提高执行效率)
例如:新建一个字符串
Stirng a1 = "abc";
String a2 = new String("abc");
这两种方式有什么区别?
String a1 = “abc”;
这种创建方式会在字符串常量池中查找是否存在,不存在则在池中新建一个字符串,栈中对象变量a1中存放的内存地址指向常量池中创建的"abc"对象;存在的话String a中存放"abc"在常量池中的内存地址
String a2 = new String(“xyz”);
这种方式会在堆内存中新建一个String对象,栈中变量a2保存的内存地址指向了堆中的String对象,堆中的String对象保存的内存地址指向了方法去常量池中的"xyz"对象;
现在回到开始的问题,解决问题之前,需要明确一点,Java中的==比较的是变量中保存内存地址是否相同:
1,字符串常量池中已经有"abc"了,所以变量a 和变量b保存的内存地址指向了字符串常量池中同一个"abc",所以结果为true
2,每次使用new都会在堆中新建一个String类型对象,所以s1和s2中保存的内存地址指向了堆中的不同String对象,所以结果为false;同时很明显,一共创建了3个对象,堆中2个,字符串常量池中1个.
小结:Java中字符串的比较不要使用"==",使用equals方法,虽然String类继承的Object的equals方法也是比较的内存地址,但是String类已经重写过了!!!
继续!
我们在打印字符串的时候,会发现输出的是字符串本身,而不是内存地址
String ss = "Hello World!!"
System.out.println(ss) //==> Hello World
这说明String类已经重写了toString()方法