Java中字符串String类型的细节

Java中String类型细节
一 . String两种初始化方式
1 . String str1= “abc”;//String类特有的创建字符对象的方式,更高效在字符串缓冲区中检测”abc”是否存在若存在则不重复创建,将地址赋值给str1.若不存在,则在字符串缓冲区中创建对象并赋地址给str1.
2 . String str1= new String( “abc”); //构造函数初始化 或者 char [] ch={‘a’,’b’,’c’}; String str1=new String (ch);先有 “abc” 对象,然后拷贝给构造函数创建的对象(相当于str1得到的是构造函数的副本)String对象是不可变的,它的内容不能改变,而在程序中字符串频繁使用,为了提高效率,对具有相同字符串序列的字符串直接量使用同一个实例,这样的实例被称之为限定的(interned)注意,第二种方式的参数只支持字符串直接量或字符数组创建,这种方式是错误的 String strA = “asd”;String strbB = new Strint(strA);比较两种创建方式,第一种更高效,只创建了一个对象,第二种创建了两个对象。
二 . 初始化细节栈中保存基本类型与对象的引用,基本类型在创建前会查看Stack中是否已经有, 有则赋值指向, 没有则创建。String str1= “abc”;String str1= new String( “abc”);前者首先在栈中创建一个引用型变量str1,然后查看栈中是否存在“abc”如果没有,则将“abc”存放进栈,并令引用变量str指向它;如果有,则直接令str1指向它;后者是java中标准的对象创建方式,其创建的对象将直接放置到堆中,每调用一次就会创建一个新的对象。String str = “abc”+”def”;这条语句创建对象个数? 1个。编译器会自己调用Stringbuilder的append方法来合成abcdef,最后只生成一个对象.实际上,字符串直接量属于常量,在编译的时候已确定,两个常量相加,先检测栈内存中是否有”abcdef” 如有有,指向已有的栈中的”abcdef”空间,若没有,则创建。

package stringDemo;

public class stringInitial
{

    public static void main(String[] args)
    {
    String str1 = "abc";
    String str2 = new String("abc");
    // String str2 = new String(new char[] { 'a', 'b', 'c' });
    // String str2 = new String(str1);错误写法

    System.out.println(str1 == str2);// false
    System.out.println(str1.equals(str2));// true这里的equals()方法已经被覆盖,比较的是字符串不是地址

    String str3 = "123";
    String str4 = "abc123";
    String str5 = "abc" + "123";
    String str = str1 + str3;
    System.out.println(str4 == str5);// true
    System.out.println(str4 == str1+"123");// false
    System.out.println(str4 == str);// false

    }

}


可以看出,只要是+中出现非字符串直接量,就会在堆中产生新的对象,并不会检测栈内存
三.关于String str=null;String str;String str=”“;String str=null;声明了一个String的引用型变量并初始化为空,及未指向任何地址,不占用任何空间String str;只是声明了一个String的引用型变量,并未初始化(作为对象属性时会有默认的隐式初始化str=null),如果后面未用此变量编译会通过String str=”“;正常的字符串初始化,只不过字符串内容为空。

上一篇:2021926学习总结


下一篇:python基础语法(五)字符串