韩顺平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);
        }

 

posted @ 2021-12-27 14:25  紫英626  阅读(60)  评论(0编辑  收藏  举报

紫英