zoukankan      html  css  js  c++  java
  • java中String new和直接赋值的区别

        Java中String new和直接赋值的区别

        对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。

    例如:

    String str1="ABC"; 和String str2 = new String("ABC"); 

    String str1="ABC" 可能创建一个对象或者不创建对象,如果"ABC"这个字符串在Java String池里不存在,会在java String池创建这个一个String对象("ABC").如果已经存在,str1直接reference to 这个String池里的对象。

    String str2 = new String("ABC") 至少创建一个对象,也可能两个。因为用到new 关键字,会在heap创建一个 str2 的String 对象,它的value 是 "ABC".同时,如果"ABC"这个字符串在java String池里不存在,会在java String池创建这个一个String对象("ABC").

    String 有一个intern() 方法,native,用来检测在String pool是否已经有这个String存在。

    public String intern()

    返回字符串对象的规范化表示形式。

    一个初始时为空的字符串池,它由类 String 私有地维护。

    当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

    它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

    所有字面值字符串和字符串赋值常量表达式都是内部的。

    返回:

    一个字符串,内容与此字符串相同,但它保证来自字符串池中。

    考虑下面的问题:

    String str1 = new String("ABC");
    String str2 = new String("ABC");

    str1 == str2 的值是True 还是False呢? False.

    String str3 = "ABC";
    String str4 = "ABC";

    String str5 = "A" + "BC";

    str3 == str4 的值是True 还是False呢? True.

    str3 == str5 的值是True 还是False呢? True.

    在写代码的时候,一般不要 String str2 = new String("ABC");

    String a = "ABC";
    String b="AB";
    String c=b+"C";
    System.out.println(a==c); false


    a和b都是字符串常量所以在编译期就被确定了!

    而c中有个b是引用不是字符串常量所以不会在编译期确定。
    而String是final的!所以在b+"c"的时候实际上是新创建了一个对象,然后在把新创建对象的引用传给c.

    public static void main(String[] args) throws Exception {    
            String a =  "b" ;     
            String b =  "b" ;     
                
            System.out.println( a == b);     
            String d = new String( "d" ).intern() ;   
            String c = "d" ;    
            //String d = new String( "d" ).intern() ;     
            System.out.println( c == d);    
            System.out.println("------------------");   
            String d1 = new String( "d" ) ;   
            String e1=d1.intern();  
            String c1 = "d" ;    
            //String d = new String( "d" ).intern() ;     
            System.out.println( c1 == d1);    
            System.out.println( c1 == e1);    
            System.out.println( e1 == d1);   
            System.out.println("------------------");   
            String s1=new String("kvill");   
            String s2=s1.intern();   
            System.out.println( s1==s2 ); //s1=s1.intern()  
            System.out.println( s1+" "+s2 );   
            System.out.println( s2==s1.intern() );   
        }    
     


    运行结果:

    true
    true
    ------------------
    false
    true
    false
    ------------------
    false
    kvill kvill
    true

    s1==s1.intern()为false说明原来的“kvill”仍然存在; 

    例子代码:

    String s1 = "china";   
    String s2 = "china";  
    String s3 = "china";   
    String ss1 = new String("china");   
    String ss2 = new String("china");   
    String ss3 = new String("china");     
     

            这里解释一下,对于通过 new 产生一个字符串(假设为 ”china” )时,会先去常量池中查找是否已经有了 ”china” 对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此 ”china” 对象的拷贝对象。

            也就是有道面试题: String s = new String(“xyz”); 产生几个对象?

             一个或两个。如果常量池中原来没有 ”xyz”, 就是两个。如果原来的常量池中存在“xyz”时,就是一个。

            对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。

    java中new String和字符串池比区别是浪费空间,为什么还需要它?  

    对 于下面程序中:ss0 = new String( "hello" );是用new()来新建对象的,存于堆中。每调用一次就会创建一个新的对象。当然从节省空间的角度来讲,肯定不如str="hello",有童鞋一定 问,那要它有什么用?当时设计编译器时,为什么要设计它?马克-to-win,那我请问你,如果在你编程序时,你还不知道字符串内容怎么办?这时就用到 new String,所以,什么都有什么的用处。

  • 相关阅读:
    DVWA 黑客攻防演练(十)反射型 XSS 攻击 Reflected Cross Site Scripting
    DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)
    DVWA 黑客攻防演练(八)SQL 注入 SQL Injection
    DVWA 黑客攻防演练(七)Weak Session IDs
    DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
    DVWA 黑客攻防演练(五)文件上传漏洞 File Upload
    工作流表结构设计
    Visual Studio 2019尝鲜----新建空项目体验
    《使用CSLA 2019:CSLA .NET概述》原版和机译文档下载
    .NET快速开发平台的在线预览
  • 原文地址:https://www.cnblogs.com/printN/p/7219279.html
Copyright © 2011-2022 走看看