韩顺平Java26——包装类02(String)
String类
-
String类的理解和对象创建
String name = "tom";
这里 name 是变量,tom是常量,可以将新的字符串赋值给变量name
name = "jack";
- 我们先来看一下继承关系
- 接着看一下String类的源码
public final class String
可以看到String是final类型的,即不可被其它类继承
/** The value is used for character storage. */ private final char value[];
这里说明String类型底层是存在一个 final的char数组中的,也就是一旦存储就不可修改(这里的不可修改指的是value数组不能指向一个新的地址,但是单个的字符内容是可以修改的)
可以看到,修改数组的某个内容是可以的,但是不能将其指向一个新的内存地址(数组)
-
创建String对象的两种方式以及区别
-
小练习
1.
String类重写了父类(Object)的equals()方法,是逐一比较两个char类型数组的元素,有一个不一样则返回假
==比较的则是两个字符串在常量池中的地址
2.
3.
b指向的是堆,b.intern()指向的是常量池,所以==判定为false
在调用”ab”.intern()方法的时候会返回”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用。 总之返回的是(指向方法区常量池的)引用(地址)。
4.
5.
s1和s2指向的是不同的堆中的地址所以不相等(虽然这两个堆指向的都是一个字符串)
6.
在执行s1=“haha”是,s1先在现有的常量池中寻找是否有“haha”这个字符串,如果有就重新指向,如果没有就先创建一个“haha”再重新指向。
所以创建了两个对象
这里如果是String s1 = new String("hello") s1是指向堆区的value,value 是final 不能改变value指向的地址,但这里是直接指向常量池,所以可以改变地址(我的意思是如果指向另一个新的字符串引用)
value数组是final修饰的,所以value的这个引用是不能发生改变的,里面的value数组又被私有化,所以你拿不到指向每一个字符的引用,因此字符串具有只读属性。
像之前老师举的例子,你是能拿到具体的每个字符的地址的 。value[] 和value[0] 这两个的意义是不一样的,前者是指向整个字符串的地址,它的本身的值就是地址,后者是值。
关于常量池中存放数据的说法
按照 《深入理解JVM虚拟机》 这本书中的说法 是 放的引用
JVM源码中 字符串常量池的创建和查找。 发现确实是对象实例。
但是目前主流说法是 字符串引用
-
String面试题
1.
2.
一定要学会自己看源码学习!!!
因为一个指向的是池一个指向的是堆。
3.
注意,change()方法中的str和ch只是和类属性同名的局部变量!而这个局部的str和ch在方法执行完毕后就进行了退栈,所以ex.str指向的还是hsp没有变化。 ex.str 赋给 str 还是值传递, 把地址传给了str,str后来的指向修改了,但是ex.str没有修改
-
String的常用方法
- substring有两种参数类型
public String substring(int beginIndex)——从开始索引到结尾
或
public String substring(int beginIndex, int endIndex) ——(开始索引,结束索引]
hello 注意是截取到第五个字符,不是截取五个,如果改成(2,5)则输出llo
第一个是大写、第二个是小写、第三个是字符串拼接
在对字符串进行分割的时候,如果有特殊字符需要在里面加上转义字符,例如需要分割的是// 则需要写成////
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
大概意思就是如果两个字符串长度相等,就比较第一个不相等的两个字符,返回两个char类型的差值。
如果长度不相等则返回两个字符串的长度差(都是第一个减去第二个) 如果长度和内容完全相同就返回0。
6.
类似C语言
判断字符串值
可以采用以下写法来避免空指针异常
String s = "";//这里的s应该是一个获取到的字符串 if ("666".equals(s)){ System.out.println(s); }
本文来自博客园,作者:紫英626,转载请注明原文链接:https://www.cnblogs.com/recorderM/p/15736104.html