String的原理与用法总结(3)

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

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

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

        返回:

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

4. 数据类型包装类的值不可修改。

   不仅仅是String类的值不可修改,所有的数据类型包装类都不能更改其内部的值。

5. 结论与建议:

  (1) 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,我们创建了String类的对象str。担心陷阱!对象可能并没有被创建!唯一可以肯定的是,指向 String类的引用被创建了。至于这个引用到底是否指向了一个新的对象,必须根据上下文来考虑,除非你通过new()方法来显要地创建一个新的对象。因 此,更为准确的说法是,我们创建了一个指向String类的对象的引用变量str,这个对象引用变量指向了某个值为"abc"的String类。清醒地认 识到这一点对排除程序中难以发现的bug是很有帮助的。

(2)使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。这个思想应该是 享元模式的思想,但JDK的内部在这里实现是否应用了这个模式,不得而知。

(3)当比较包装类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==。

(4)由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率 

6.这里有几个问题(进阶版):

  (1) String a1 = new String("abc") 在运行时涉及几个String实例?

         两个,一个是字符串字面量"xyz"所对应的、驻留(intern)在一个全局共享的字符串常量池中的实例,另一个是通过new String(String)创建并初始化的、内容与"xyz"相同的实例

    (2) String a1 = new String("abc") 涉及用户声明的几个String类型的变量?

        一个,就是String s。
    (3)String s = null 涉及用户声明的几个String类型的变量?
        一个。Java里变量就是变量,引用类型的变量只是对某个对象实例或者null的引用,不是实例本身。声明变量的个数跟创建实例的个数没有必然关系

    (4)

String s1 = "a"

String s2 = s1.concat(""); 

String s3 = null

new String(s1); 

      这段代码会涉及3个String类型的变量, 
      1、s1,指向下面String实例的1 
      2、s2,指向与s1相同 
      3、s3,值为null,不指向任何实例 

      以及3个String实例, 
    1、"a"字面量对应的驻留的字符串常量的String实例 
    2、""字面量对应的驻留的字符串常量的String实例 
        (
是个有趣的方法,当发现传入的参数是空字符串时会返回this,所以这里不会额外创建新的String实例) 
    3、通过new String(String)创建的新String实例;没有任何变量指向它。 

(5)如下每执行一次创建了几个实例:

String s1 = new String("xyz"); 

String s2 = new String("xyz"); 

        每执行一次只会新创建2个String实例。 
       

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f8f82c9503d2e6173b692f3b941e75a2.html