• Day32.String内存特性(不可变性、实例化方式、字符拼接) -Java常用类#、集合、IO


    String的内存特性

    .

    String的不可变性

    • String类:代表字符串。Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现。

    • String是一个final类,代表不可变的字符序列

    • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。

    • String对象的字符串内容是存储在一个字符数组Value[]中的。

      public final class String
      implements java.io.Serializable, Comparable, CharSequence {
      /** The value is used for character storage. */
      private final char value[];

      /** Cache the hash code for the string */
      private int hash; // Default to 0
      
      
          String s1 = "abc";//字面量的定义方式
          String s2 = "abc";
          
          System.out.println(s1 == s2);//比较s1与s2地址值 True
      	String s1 = "hello"//当对字符串重新赋值时,需要重新指定另一个内存区域来赋值,不能使用原来有value进行赋值。
      
      	//通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在常量池中。
      	//字符串常量池中是不会存储相同内容的字符串的。
      
      	String s3 = "abc";//
          s3 += "def";//重新新建分配内存区域
          System.out.println(s3);//abcdef
      	//当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能在原有的Value进行赋值
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    在这里插入图片描述

            String s4 = "abc";
            String s5 = s4.replace('a', 'm');
    
            System.out.println(s4);//abc
            System.out.println(s5);//mbc
    		//就算不改变字符长度的修改(abc --->mbc)也需要重新指定内存区域来赋值
    		//当调用String的replace()方法修改指定的字符或字符串时,也需要重新指定内存区域赋值,不能在原有的Value进行赋值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    //String不可变性
    public class StringTest {
    
        /*
        String:字符串,使用一对""引起来表示
        1.String声明为final的,不可被继承
        2.String实现了Serializable接口:表示字符串是可支持序列化的。
                实现了Comparable接口:表示字符串可比较大小。
        3.String内部定义了final char[] value用于存储字符串数据
        4.String:代表不可变的字符序列。简称:不可变的性
                体现:1.当对字符串重新赋值时,需要重新指定另一个内存区域来赋值,不能使用原来有value进行赋值。
                     2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能在原有的Value进行赋值
                     3.当调用String的replace()方法修改指定的字符或字符串时,也需要重新指定内存区域赋值,不能在原有的Value进行赋值
        5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在常量池中。
        6.字符串常量池中是不会存储相同内容的字符串的。
         */
    
        @Test
        public void test1(){
            String s1 = "abc";//字面量的定义方式
            String s2 = "abc";
    
            System.out.println(s1 == s2);//比较s1与s2地址值 True
    
            s1 = "hello";
            System.out.println(s1);//hello
            System.out.println(s2);//abc
    
            System.out.println("===========================");
    
            String s3 = "abc";
            s3 += "def";
            System.out.println(s3);//abcdef
    
            System.out.println("==============================");
            String s4 = "abc";
            String s5 = s4.replace('a', 'm');
    
            System.out.println(s4);//abc
            System.out.println(s5);//mbc
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    String的实例化方式

    /* String的实例化方式:
    
     方式一:通过字面量定义的方式
     方式二:通过new + 构造器的方式
    
        面试题:String s =new String("abc");方式创建对象,在内存中创建了几个对象?
                两个:一个是堆空间中new的结构,另一个是char[]对应的常量池的数据"abc"
                
    */
    
    
        public void test2(){
            //方式一:通过字面量定义的方式:此时的s1和s2的数据"javaEE"声明在方法区的字符串常量池中。
            String s1 = "javaEE";
            String s2 = "javaEE";
    
            //方式二:通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
            String s3 = new String("javaEE");
            String s4 = new String("javaEE");
    		
            //比较内存值
            System.out.println(s1 == s2);//true
            System.out.println(s1 == s3);//false
            System.out.println(s1 == s4);//false
            System.out.println(s3 == s4);//false
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    //方式二:通过new + 构造器的方式
    		Person p1 = new Person("Tom",12);
            Person p2 = new Person("Tom",12);
    
            System.out.println(p1.name.equals(p2.name));//true
            System.out.println(p1.name == p2.name);//true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    String字符拼接

        public void test3(){
            String s1 ="javaEE";
            String s2 ="hadoop";
    
            String s3 = "javaEEhadoop";
            String s4 = "javaEE" + "hadoop";
            String s5 = s1 +"hadoop";
            String s6 = "javaEE" + s2;
            String s7 = s1 + s2;
    
            System.out.println(s3 == s4);//true
            System.out.println(s3 == s5);//false
            System.out.println(s3 == s6);//false
            System.out.println(s3 == s7);//false
            System.out.println(s5 == s6);//false
            System.out.println(s5 == s7);//false
            System.out.println(s6 == s7);//false
    
            String s8 = s5.intern();//返回值得到的s8使用的常量池已经存在的"javaEEhadoop"
            System.out.println(s3 == s8);//true     
        }
            public void test4(){
            String s1 = "javaEEhadoop";
            String s2 = "javaEE";
            String s3 = s2 + "haddop";
            System.out.println(s1 == s3);//false
    
            final String s4 = "javaEE";//s4:常量
            String s5 =s4 + "hadoop";
            System.out.println(s1 == s5);//true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    /*
        
        结论:
        1.常量与常量的拼接结构在常量池,且常量池中不会存在相同的常量。
        2.只要其中有一个是变量,结果就在堆中
        3.如果拼接的结果调用intern()方法,返回值就在常量池中
    
    */
    
    
    //面试题
    public class StringTest {
        String str = new String("good");
        char[] ch = {'t','e','s','t'};
    
        public void change(String str,char ch[]){
            str = "test ok";
            ch[0] = 'b';
        }
    
        public static void main(String[] args) {
            StringTest ex = new StringTest();
            ex.change(ex.str,ex.ch);
    
            System.out.println(ex.str);//good String的不可变性
            System.out.println(ex.ch);//best 数组还是照样的被改变
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    linux下mysql的三种安装方法
    liunx jmter 环境配置
    【Python 算法】信号处理通过陷波滤波器准确去除工频干扰
    vue路由传参刷新丢失
    Ajax学习:设置CROS响应头实现跨域(跨域资源共享)
    5、超链接标签
    CH34X-MPHSI高速Master扩展应用—SPI设备调试
    幂等幂等幂等
    C++ 享元模式
    Spring @Component注解详解
  • 原文地址:https://blog.csdn.net/m0_67402235/article/details/126327058