关于java jdk中内置的一个类:java.lang.String
1、String表示字符串对象,属于引用数据类型,不属于基本数据类型
2、在java中随便使用双引号括起来的都是String对象。例如:“abc”、“def”、“HElloWorld”这3个String对象
3、java规定,双引号括起来的字符串,是不可变的,也就是说“abc”自出生至死,不可变,不能变成“abcd”,也不可能变成“ab”
4、在jdk中双引号括起来的字符串,例如“abc”、“def”都是直接存储在“方法区”的“字符串常量池”当中的
为什么SUN公司把字符串存储在一个“字符串常量池”当中呢。因为字符串在实际的开发中使用太频繁。为了
执行效率,所以把字符串放到了方法区的字符串常量池当中。
示例代码01:
public class StringTest01 { public static void main(String[] args) { //这两行代表示底层创建了3个字符串对象,都在字符串常量池当中 String a = "abcdef"; String b = "abcdef" + "xy"; //分析:这是使用new的方式创建的字符串对象。这个代码中的“xy”是从哪来的? //凡是双引号括起来的都在字符串常量池中有一份 //new对象的时候一定在堆内存当中开辟空间 String c = new String("xy"); } }
内存分析图01:
示例代码02:
public class StringTest02 { public static void main(String[] args) { //"hello"是存储在方法区的字符串常量池中 //所以这个“hello”不会创建。(因为这个对象已经存在了!) String s = "hello"; String s1 = "hello"; //分析结果是true还是false //双等号比较的是不是变量中保存的内存地址?是的 System.out.println(s == s1);//true String s2 = new String("xy"); String s3 = new String("xy"); System.out.println(s2 == s3);//false //String类重写了equals方法,所以使用equals方法比较保险 //通过此案例,我们知道,字符串对象之间的比较不能使用“==” System.out.println(s2.equals(s3));//true String s5 = new String("testString"); System.out.println(s3.equals("testString"));//false存在空指针异常,不建议这样写 //String k = null; //"testString"这个字符串可以后面加“.”呢? //因为“testString”是一个String字符串对象。只要是对象都能调用方法。 System.out.println("testString".equals(s3));//false建议使用此方式,因为此方式可以避免空指针异常 } }
内存分析图02:
示例代码03:
class User { private int no; private String name; public User(){ } public User(int no,String name){ this.no = no; this.name = name; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class UserTest { public static void main(String[] args) { User u = new User(100,"张三"); } }
内存分析图03:
常见面试题:
public class StringTest03 { public static void main(String[] args) { //一共创建了3个对象 //方法区的常量池中创建了一个对象“hello” //堆内存创建了两个对象 String s1 = new String("hello"); String s2 = new String("hello"); } }