认识String类(一)

发布时间:2023-12-01 09:30

目录

1.初识字符串

 2.字符串常量池

3.反射修改常量字符串


1.初识字符串

         Java中,字符串类型就是我们用双引号引起来的连续字符,如:\"abcdef\",而\'a\'这种的只是字符,String只是字符串的类型。

那我们接下来看看一些字符串是否相等的例子:

 public static void func(String s,char[] array){
        s = \"hang\";
        array[0] = \'p\';
    }

    public static void main(String[] args) {
         String str = \"abcdef\";
         char[] chars = {\'b\',\'i\',\'t\'};
         func(str,chars);
        System.out.println(str);
        System.out.println(Arrays.toString(chars));
    }

\"认识String类(一)_第1张图片\"

 下面我们看看此题的内存布局:

\"认识String类(一)_第2张图片\"

 2.字符串常量池

运行时常量池:当程序把编译好的字节码文件加载到JVM中,会生成一个运行时常量池(存储在方法区)实际上是class文件常量池。

字符串常量池:主要存放字符串常量,本质上是一个哈希表,StringTable.在JDK1.8开始,放在了堆里面。

例2:

        String str1 = \"hello\";//双引号引起来的存放到字符串常量池里面
        String str2 = new String(\"hello\");
        System.out.println(str1 == str2);
//其结果是false

下面是其内存布局:

\"认识String类(一)_第3张图片\"

 例2:

String str1 = \"hello\";
String str2 = \"hello\";
System.out.println(str1 == str2);

这其中str1先入常量池,随后str2直接引用常量池中的hello,因此两者相等。并且str2并不会入池。

例3:

        String str1 = \"11\";
        String str2 = new String(\"1\")+new String(\"1\");
        System.out.println(str1 == str2);

\"认识String类(一)_第4张图片\"

 例4:

        String str2 = new String(\"1\")+new String(\"1\");
        str2.intern();//手动入池,字符串常量池没有的时候,就会入池,有则不会入池
        String str1 = \"11\";
        System.out.println(str1 == str2);

          此时两个1互相拼接之后,内存布局和上述相同,可是调用intern( )方法之后,我们将str2手动入池,之后再有str1=11调用常量池中的11,因此结果为true.

        但如果我们将str1和str2位置交换,则结果会变为false。这是因为str1先入池,之后intern( )时,常量池已经有11,因此str2不会入池。

        String str1 = \"11\";
        String str2 = new String(\"1\")+new String(\"1\");
        str2.intern();//手动入池,字符串常量池没有的时候,就会入池,有则不会入池
        System.out.println(str1 == str2);

\"认识String类(一)_第5张图片\"

 如果我们想比较字符串的内容时,则使用equals方法,但在使用之前我们应该先判断str1是否为空

public class TestDemo2 {
    public static void main7(String[] args) {
        String str1 = null;//代表str1这个引用不指向任何对象
        String str3 = \"\";//代表str3这个引用指向的字符串是空的
        String str2 = \"11\";//String底层是个value数组,此时11不能被改变,如果想改变,只能用反射
        //调用方法之前一定是个引用或者类名,因此一定要防止其为空
        System.out.println(str1.equals(str2));
    }

3.反射修改常量字符串

public static void main(String[] args) throws NoSuchFieldException {
       String str = \"aello\";
       Class c1 = String.class;
        // 获取 String 类中的 value 字段. 这个 value 和 String 源码中的 value 是匹配的.
        Field valueField = c1.getDeclaredField(\"value\");
       // 将这个字段的访问属性设为 true
        valueField.setAccessible(true);
       // 把 str 中的 value 属性获取到.
        char[] value = (char[]) valueField.get(str);
       // 修改 value 的值
        value[0] = \'h\';
        System.out.println(str);
    }
//此时通过反射将字符串改为hello

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号