一、String类
1.概述
String类代笔的是字符串,是引用数据类型,Java中的所有字符串文字都可以被看成是这个类的实现
字符串表面上看起来存储的是一个字符数组,但是其底层实际上存储的是字符数组对应的字节数组。
2.常用构造方法
1 //初始化一个新创建的 String 对象,使其表示一个空字符序列。 2 public String(); 3 String string1 = new String(); 4 string1 = "abc"; 5 6 // 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。 7 public String(char[] chars); 8 char[] ch = {'a','b','c'}; 9 String string2 = new String(ch); 10 11 //通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。 12 public String( byte[] value); 13 byte[] b = {97, 98, 99}; 14 String string3 = new String(b); 15 16 //直接创建 17 String string4 = "abc";
下面咱们来说一说这四种创建方式,
前三种创建方式是引用类型常见的创建方式,都是先在栈中定义一个String类型的变量,然后在堆中new一块空间出来,把这块空间的地址赋给栈中的变量
但是String类既然是引用数据类型,那为什么可以不用new就可以直接创建呢?
在聊这个之前就不得不说一下Java虚拟机(jvm)的底层划分了,
Java虚拟机分为五个部分,分别是栈,堆、方法区、,用一张图片说明一下,没啥美术天分,画的比较丑
接着上个问题,为什么string可以像基本数据类型那样直接赋值?
在jvm的堆内存中有一块东西叫做字符串常量池,在赋值的时候把里面的一个地址赋给了string ,常量池中的的这个地址又指向的是堆中的一个字节数组,根据ASCII码表可知其实这样就相当于存储了对应的字符
3.字符串值的比较
1 String str1 = "abc"; 2 3 String str2 = "abc"; 4 5 String str3 = "a"; 6 7 String str4 = "bc"; 8 9 char[] ch = {'a','b','c'}; 10 11 String str5 = new String(ch);
上面的代码中,来做个比较,(引用类型比较值是通过重写Object类型的equals方法实现的,String类重写过这份方法)
str1 == str2结果竟然是神奇的true,大家都知道字符串是引用类型,引用类型是不能直接进行比较的,直接比较结果相等意味着二者的地址值相等,这也就是说他们两个存储的是同一个地址,为什么呢?这就是前面说过的字符串常量池的原因了,如果给字符串直接赋值,它默认是调用字符串常量池里的内容的所以二者的地址其实都是指向了字符串常量池中的。
str1 == "a" + "bc";结果也是true,其实咱们的JVM是很智能的,在编译的时候虚拟机给我们的代码做了优化,其实就和第一种情况是一样的
str1 == str3 + "bc"; 这时候结果就出现变化了,因为整个出现了变量,在编译的时候虚拟机遇到变量就不会帮你把表达式转换成第一种情况了。
str1 == str4 这个结果其实大家已经可以想到了,结果是false,因为二者的地址是完全不一样的。
语言表达能力实在有限,放一张图把,图片来源黑马的培训视频。
写文章的目的是为了让自己以后查找起来更加便捷一点,可能会右很多错误,以后慢慢再来更正。