zoukankan      html  css  js  c++  java
  • 关于String str =new String("abc")和 String str = "abc"的比较--转

    原文地址:https://www.cnblogs.com/OnlyCT/p/5433410.html

    String是一个非常常用的类,应该深入的去了解String

    如:

    String str =new String("abc")

    String str1 = "abc"

    System.out.println(str == str1)

    System.out.println(str.equal(str1))

    结果:

    false

    true

    原因解析:

    • Java运行环境有一个字符串池,由String类维护。

     1. 执行语句String str="abc";时。首先查看字符串池中是否存在字符串"abc",如果存在则直接将“abc”赋给str,如果不存在则先在  字 符串池中新建一个字符串"abc",然后再将其赋给str.

     2. 执行语句String str = new String("abc");时。不管字符串池中是否存在字符串“abc”,直接新建一个字符串“abc”,(注意,新建的字符串“abc”不是在字符串池中), 然后将其赋给str。由此可见 1.的效率要高于2的效率。


     3. String str1="java";//指向字符串池
         String str2="blog";//指向字符串池
           String   s = str1+str2;

      +运算符会在堆中建立起两个String对象,这两个对象的值分别是“java”,"blog",也就是说从字符串常量池中复制这两个值,然后再堆中创建两个对象。然后再建立对象s,然后将“javablog”的堆地址赋给s.  这句话共创建了3个String对象。


           System.out.println(s=="javablog");//结果是false;

           JVM确实对形如String str="javablog";的对象放在常量池中,但是它是在编译时name做的。而String s=str1+str2;是在运行时候才能知道的,也就是说str1+str2是在堆里创建的,所以结果为false了。
          String s="java"+"blog";//直接将javablog对象放入字符串池中。        System.out.println(s=="javablog");//结果是true;

          String s=str1+"blog";//不放在字符串池中,而是在堆中分分配。       System.out.println(s=="javablog");//结果是false;

          总之,创建字符串有两种方式:两种内存区域(pool,heap)
          1.""创建的字符串在字符串池中。
          2.new 创建字符串时,首先查看池中是否有相同的字符串,如果有则拷贝一份放到堆中,然后返回堆中的地址;如果池中没有则在堆中创建一分,然后返回堆中的地址,
          3.在对字符串赋值时,如果右操作数含有一个或一个以上的字符串引用时,则在堆中再建立一个字符串对象,返回引用如:String s= str1+"blog";

    之间的区别

    第1种:

    String a="abc";
    String b="abc";
    System.out.print(a==b);

    结果:true

    原因:编译时,这两个"abc"被认为是同一个对象保存到了常量池中;运行时JVM则认为这两个变量赋的是同一个对象,所以返回true。

    ---------------------
    第2种:

    String a=new String("abc");
    String b=new String("abc");
    System.out.print(a==b);

    结果:false

    原因:用构造器创建的对象,是不会被放入常理池中的,也很明显这完全是两个对象,只是内容相同罢了,结果当然为false了。用equals()或者System.out.print(a.intern()==b.intern());就返回true了。

    ------------------------------
    第3种

    String a="abc";
    String b=new String("abc");
    System.out.print(a==b);

    结果:false

    原因:同上。此外,a的类加载时就完成了初始化,而b要在执行引擎执行到那一行代码时才完成初始化。

    ---------------------------
    第4种

    String a="abcdef";
    System.out.print(a=="abcdef");

    结果:true

    原因:运行出现的字符串常量,若是在常量池中出现过,则JVM会认为同一个对象,以节省内存开销,所以这两个字符串会被认为是同一个对象。

    -------------------------------------------
    第5种

    String a="abcdef";
    String b="";
    String c=a+b;
    System.out.print(c=="abcdef");

    结果:false

    原因:编译时,先将"abcedf"放在常量池中,而c的值则是在运行时在堆里创建的。所以为false。
    • Object o与Object o=null的区别 


    具体差别如下:
    class Test {

      public static void main(String[] args) {
      Object o1;
      o1.toString(); /*这里编译不能通过,编译器只认定o1是个引用,没指向任何对象,所以不能调用方法。*/
      Object o2 = null;
      o2.toString(); /*这里编译可以过,但是有空指针异常,编译器认定o2是一个对象,虽然是一个空对象。*/
      }
    }
    null对象是一个特殊的对象,他可以是任何类型。他只是作为一个标记而已,只是为了标记不存在而存在的。也没必要去追究他在内存是什么样。null就是一个标记而已。容器可以接受一个空对象,但是一个空引用则是不接受的。
    Object o; //这种写法只是分配一个引用,没有分配内存。
    Object o = null; //这么写则是给引用指向了一个空对象。分配了内存(空对象),所以编译不会报错,运行时报空指针异常。

  • 相关阅读:
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    linux中的cd ..和cd -命令有什么区别?
    GCC使用
  • 原文地址:https://www.cnblogs.com/tenWood/p/8595561.html
Copyright © 2011-2022 走看看