`

Java中String和String Pool

    博客分类:
  • Java
阅读更多
1. Java中String和String Pool

1. 采用字面值方式赋值
    String str = "aaa";
    String str2 = "aaa";
    System.out.println(str == str2);返回结果为true。
    
    1) 查找String Pool中是否存在"aaa"这个对象,如果不存在,则在String Pool中创建一个"aaa"对象,然后将StringPool中的这个"aaa"对象的地址返回来,赋给引用变量str,这样str会指向String Pool中的这个"aaa"字符串对象。
    2) 如果存在,则不创建任何对象,直接将String Pool中的这个"aaa"对象地址返回来,赋给s引用。

2. 采用new关键字新建一个字符串对象
    String str = new String("aaa");
    String str2 = new String("aaa");
    System.out.println(str == str2);返回结果为false。
    
    (1) 首先在String Pool中查找有没有"aaa"这个字符串对象,如果有,则不在String Pool中再去创建"aaa"这个对象了,直接在堆中(heap)中创建一个"aaa"字符串对象,然后将堆中(heap)的这个"aaa"对象的地址返回来,赋给str引用,使str指向堆中创建的这个"aaa"字符串对象。
    (2) 如果没有,则首先在String Pool中创建一个"aaa"对象,然后再在堆中(heap)创建一个"aaa"对象,然后将堆中的这个"aaa"对象的地址返回来,赋给str引用,使str指向堆中(heap)所创建的这个"aaa"对象。

3. intern()方法
    如果String Pool中包含这个对象,则返回String Pool的中的对象。否则这个对象将添加到String Pool中。
    如果a.equals(b)为true,则a.intern() == b.intern()返回结果为true。

4. 字符串池
    字符串池的优缺点:
    1) 字符串池的优点就是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;
    2) 另一方面,字符串池的缺点就是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低。
    Java语言的规范:
    1) 每一个字符串常量都指向字符串池中或者堆内存中的一个字符串实例;
    2) 字符串对象值是固定的,一旦创建就不能再修改;
    3) 字符串常量或者常量表达式中的字符串都被使用方法String.intern()在字符串池中保留了唯一的实例;
    public class Test {
        public static void main(String[] args) {
            Other other = new Other();
            String hello = "Hello", lo = "lo";
            System.out.print((hello == "Hello") + " ; ");
            System.out.print((Other.hello == hello) + " ; ");
            System.out.print((other.hello == hello) + " ; ");
            System.out.print((hello == ("Hel" + "lo")) + " ; ");
            System.out.print((hello == ("Hel" + lo)) + " ; ");
            System.out.print((hello == ("Hel" + lo).intern()) + " ; ");
        }
    }
    class Other {
        static String hello = "Hello";
    }
    运行结果:
    true ; true ; true ; true ; false ; true ; 
    (1) 同一个包下同一个类中的字符串常量的引用指向同一个字符串对象;
    (2) 同一个包下不同的类中的字符串常量的引用指向同一个字符串对象;
    (3) 不同的包下不同的类中的字符串常量的引用仍然指向同一个字符串对象;
    (4) 由常量表达式计算出的字符串是在编译时进行计算,然后被当作常量;
    (5) 在运行时通过连接计算出的字符串是新创建的,因此是不同的;
    (6) 通过计算生成的字符串显示调用intern方法后产生的结果与原来存在的同样内容的字符串常量是一样的。

5. 字符串是常量,字符串池中的每个字符串对象只有唯一的一份,可以被多个引用所指向,避免了重复创建内容相同的字符串;通过字面值赋值创建的字符串对象存放在字符串池中,通过关键字new出来的字符串对象存放在堆中。
    public class Test {
        public static void main(String[] args) {
            String test = "javastringtest";
            String sub1 = "java";
            String sub2 = "string";
            String sub3 = "test";
            System.out.println(test == "java" + "string" + "test");
            System.out.println(test == sub1 + sub2 + sub3);
        }
    }
    运行结果:
    true
    false
    (1) 字符串字面量拼接操作是在Java编译器编译期间就执行了,也就是说编译器编译时,直接把"javastringtest","java","string"这三个字面量进行"+"操作得到一个"javastringtest"常量,并且直接将这个常量放入字符串池中,这样做实际上是一种优化,将3个字面量合成一个,避免了创建多余的字符串对象。
    (2) 而字符串引用的"+"运算是在Java运行期间执行的,即ub1+sub2+sub3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。
    (3) 字面量"+"拼接是在编译期间进行的,拼接后的字符串存放在字符串池中;
        而字符串引用的"+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
分享到:
评论

相关推荐

    深入探讨Java中的String类.pdf

    Java 中的 String 类有很多特点和用途,本文将深入探讨 Java 中的 String 类。 一、String 类的本质 Java 中的 String 类是一个特殊的类,它是一个 immutable 类,也就是说,一旦创建了 String 对象,它的值就不能...

    Java String对象的经典问题

    - **直接赋值**:这种方式会在**字符串常量池**(String Pool)中查找或创建一个对应的`String`对象,并将变量指向该对象。字符串常量池是Java堆的一部分,专门用来存储字符串字面量。如果字符串常量池中已经存在...

    解析Java中的String对象的数据类型 字符串

    常量池(constant pool)是Java中的一个概念,它指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。常量池包括了关于类、方法、接口等中的常量,也包括字符串常量。例如String s0="kvill";,String ...

    Java字符串池(String Pool)深度解析.docx

    Java字符串池(String Pool)是Java虚拟机(JVM)为优化字符串操作而设计的一个特殊内存区域。它的主要目的是减少内存消耗和提高程序性能,通过存储和重用相同的字符串值来避免重复创建对象。字符串池在Java中扮演着...

    JAVA中关于String的一些注意点

    ### JAVA中关于String的一些注意点 在Java编程语言中,`String` 类是最常用的数据类型之一,用于处理文本数据。本文将深入探讨Java中的`String`类及其使用时需要注意的关键点,希望对开发者们有所帮助。 #### 1. ...

    JAVA面试题解惑系列(二)——到底创建了几个String对象-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    在 JAVA 中,存在一个字符串池(String Pool),用于保存和共享 String 对象。String 对象池可以提高效率,因为它可以避免创建重复的 String 对象。 String 对象池是由 String 类维护的,可以通过 intern() 方法来...

    java面试笔试题String 和StringBuffer的区别

    在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...

    java 连接池 pool 实例

    在Java应用程序中,频繁地创建和销毁数据库连接是非常低效的。为了提高性能和资源利用效率,通常会使用数据库连接池来管理这些连接。连接池预先创建一定数量的数据库连接,并将它们保存在一个池中,当应用程序需要...

    Java中关于String的全面解析

    Java中的String是一个非常重要的类,它提供了两种创建方式和一种特殊的存储机制(String intern pool),并且String类中声明了一个char[]数组和一个int类型的变量hash,用于存储字符串的内容和哈希值。

    javaString总结共13页.pdf.zip

    这份"javaString总结共13页.pdf.zip"压缩包文件显然包含了关于Java字符串的深入讲解,覆盖了多个关键知识点。虽然没有提供具体的PDF内容,但我可以基于常见的Java String主题为你概述一些重要的概念。 1. **字符串...

    String容量大小区分

    该标题及描述强调了在Java编程中,对String类型数据容量的理解和掌握。字符串在程序设计中极为常见,尤其是在处理文本文件时更是不可或缺。Java中String对象具有不可变性(immutable)的特点,这意味着一旦创建了一...

    java中Object对象String对象的解析.pdf

    对于`String`对象,它们在Java中的处理和比较有一些特殊的规则。 1. **对象的相等性比较**: - 原生数据类型的比较:原生数据类型(如int、double等)直接比较的是数值是否相同。 - 引用类型的比较:引用类型比较...

    redis-2.1.0 和commons-pool-1.5.6 Java测试redis values 类型

    以上就是关于"redis-2.1.0"和"commons-pool-1.5.6"在Java中测试Redis值类型的一些关键知识点。通过这些测试,开发者可以确保Java应用程序能够正确、高效地与Redis交互,利用其丰富的数据结构特性实现各种业务需求。

    string中的常见问题

    在Java编程语言中,`String` 类型是最常用的数据类型之一,它代表了不可变的字符序列。本文将基于提供的代码片段深入探讨与 `String` 类型相关的几个关键概念,包括字符串常量池、字符串比较、以及 `new` 关键字在...

    深入理解JavaString#intern()内存模型Ja

    `intern()`方法是一个非常特殊的函数,它将字符串常量池(String Constant Pool)的概念引入到我们的讨论中。 字符串常量池是Java虚拟机(JVM)内存模型的一部分,位于堆内存的常量池区域。在Java 6及之前,这个池...

    Java常用类与基础API-String的理解与不可变性

    在JDK 8中,字符串常量存储在永久代(Permanent Generation)中的字符串池(String Pool)中。字符串池是一个特殊的内存区域,用于存储共享的字符串字面量,这有助于避免重复创建相同的字符串对象。 ```java // 示例...

    Java8中文文档

    7. **并发改进**:Java 8在并发处理方面也有所增强,例如`ForkJoinPool`和`Parallel Streams`,它们利用多核处理器的并行计算能力,加速了大量数据的处理速度。 8. ** Nashorn JavaScript引擎**:Java 8集成了...

    浅谈java String不可变的好处

    在上面的代码中,我们可以看到a和b指向的是同一个String pool中的对象,而c则是以new创建的对象,保存在堆中。 实现String pool就需要String定义为final,否则,当引用a、b都指向“abc”时,通过a将对象改变后,...

    String类创建对象问题

    **常量池(Constant Pool)**:在 Java 编译阶段确定的数据集合,存储在 `.class` 文件中。它包含了类、方法和接口的常量数据,也包括字符串常量。 **字符串池**:这是 JVM 内部的一个特殊结构,用于存储字符串字面...

Global site tag (gtag.js) - Google Analytics