Java记录 -26- StringPool和字面赋值

Java中的String类在开发中使用比较频繁,所以JDK的开发者对String类进行了很多优化。

Java中维护着一个StringPool字符串池的概念。

Java中String类的字面赋值和 new 赋值的不同。

1.      String a1 = "bb";
        String a2 = "bb";
        System.out.println(a1 == a2);

上面的输出结果为true,这是为什么呢?

StringPool(字
符串池),对于字符串来说,Java会维护者一个字符串池的概念。当使用字面量直接给一个字符串进行赋值的时候,实际上做了两件事情:首先检查字符串池中
有没有内容为该字符串内容的字符串存在,没有则将该字符串放入字符串池里,并创建字符串对象返回对象地址给引用;当再次赋值同一个字符串时会再次判断字符
串池里是有存在该字符串,存在则不会再创建对象而是直接将地址返回给引用。这样多个引用就会指向同一个对象。

2.String s = "aaa";

以上代码采用字面值的方式赋值需要执行以下几步操作:

1).查找StringPool中是否存在“aaa”这个对象,如果不存在,则在StringPool中创建一个“aaa”对象,然后将StringPool中“aaa”的地址返回,赋给引用变量s,这样s会指向StringPool中的这个“aaa”字符串对象。

2).如果存在则不创建任何对象,直接将StringPool中的这个“aaa”对象地址返回,赋给s引用。

3.      String s1 = new String("aa");
        String s2 = new String("aa");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));

上面的代码输出中第一个为false,第二个为true。第二个为true好理解,以前说过,String类的equals比较两个字符串的内容是否一致。但第一个为false,难道没有使用上面刚提到的StringPool吗?

内存主要区域为堆和栈,StringPool字符串池是在java的栈中,而我们new出来的对象都是在java的堆中。

4.String s = new String("aaa"); //String使用new来创建对象时,同样也利用了StringPool

1).首
先会在StringPool中查找是否存在“aaa”该字符串对象,如果存在则不会再在StringPool创建“aaa”这个对象了,而是会在堆中直接
去创建一个“aaa”字符串对象,并且将堆中创建的对象地址返回给s引用,导致s指向了堆中创建的这个“aaa”字符串对象;

2).如果不存,则首先会在StringPool中创建一个“aaa”字符串对象,然后再在堆中创建一个“aaa”字符串对象,并且将堆中创建的对象地址返回给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。

5.在使用new创建字符串时,不管StringPool中是否存在该字符串对象,在堆中都会创建一个该字符串对象,并返回地址给引用。所以new创建的字符串对象都是指向堆中的地址。

String特麻烦,针对不同的JDK实现,String的实现也不同。

时间: 2025-01-09 21:53:17

Java记录 -26- StringPool和字面赋值的相关文章

java String 两种不同的赋值 比较

原文http://blog.163.com/[email protected]/blog/static/1271436362012101214031911/ 在此感谢博主写出这么优秀的文章. 首先明确一点,String是一个类.下面我们主要讨论两个问题  a) String类的对象的两种赋值方式  b) 为什么String类的对象可以直接赋值  a) 1 类似普通对象,通过new创建字符串对象.String str = new String("Hello"); 内存图如下图所示,系统会

Java笔记(26):网络编程

1.网络模型概述和图解 网络模型7层概述:1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后在转化为1.0,也就是我们常说的数模转换与模数转换).这一层的数据叫做比特. 2. 数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装.常把这一层的数据叫做帧.在这一层工作的设备是交换机,数据通过交换机来传输. 3. 网络层:主要将从下层接收到的数据进行IP地

【Java记录】try-with-resources的一个坑

[Java记录]try-with-resources的一个坑 今天处理 AsynchronousFileChannel 时候的一个问题,代码如下: public static void main(String[] args) throws Exception { String filePath = "/home/xe/git/osc/JavaNote/Lang/data/Test.java"; ExecutorService executorService = Executors.ne

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

    Java中String new和直接赋值的区别     对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中.对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份. 例如: String str1="ABC": 和String str2 = new String("ABC"); String str1="ABC" 可能创建

Java和C#中String直接赋值与使用new创建(==与equals进行比较)的区别

在Java中,字符串可以直接赋值或者使用new来新建,直接赋值的话是编译阶段(.class文件)中就将该字符串值放到常量池中,以后如果有其他变量直接赋予同样的值的话就不再分配内存空间,而是直接给它个引用地址:而使用new来创建的话是在程序运行时才分配的空间,是一个新的引用地址,可以通过inter()方法将字符串加入的常量池中,如果在常量池中已经存在该字符串,则返回其引用.在String类中,==是比较两个字符串的引用地址是否相同,equals比较的是两者的值是否相同(在其他的引用类中==和equ

java记录在线人数小案例

文件目录: web.xml: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLoc

Java中String的两种赋值方式的区别

本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过"字面量"赋值,如:String str="hello",第二种是通过new关键字创建新对象,如:String str=new String("hello").那么这两种赋值的方式到底有什么区别呢,下面给出具体分析. 1.首先回顾Java虚拟机的结构图. 在上面的

Java反射 - 简单的给Bean赋值和取值

由于项目的实际需要,所以利用java反射原理写了一个简单给bean赋值和取值通用的类,在此记录下方便自己日后用到,也为需要的兄弟提供个参考例子. 工具类BeanRefUtil: [java] view plain copy print? package com.test; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.u

java记录对象前后修改的内容(工具类)

有时候业务需要,需记录一条记录的修改历史,但是不能为完成任务而硬编码,不靠谱 这种情况可以使用java反射来完成 对对象属性的描述可以通过自定义注解来完成,读取里面的属性进而记录修改历史. 在对象的属性上面加上注解,value设置为属性的中文描述 工具了代码如下 util类(BeanChangeUtil) 1 import java.beans.PropertyDescriptor; 2 import java.lang.reflect.Field; 3 import java.lang.ref