栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

浅谈java中==,equal(),String.intern()的原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅谈java中==,equal(),String.intern()的原理

在学习String类型时,看到使用引用型变量作为方法的输入参数举例,于是查阅有关资料,大概对其做了了解。

一.首先要了解什么是字符串常量池(String Constant Pool)

        字符串在java程序中被大量使用,为了避免每次都创建相同的字符串对象及内存分配,JVM内部对字符串对象的创建做了一定的优化,在Permanent Generation中专门有一块区域用来存储字符串常量池(一组指针指向Heap中的String对象的内存地址)。

        程序运行时,可以通过String类的intern()方法动态地扩充字符串常量池。当调用 intern 方法时,如果池已经包含一个等于此String对象的字符串(用 equals(object)方法确定),则返回池中的字符串。否则,将此String 对象添加到池中,并返回此String对象的引用。所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。

创建字符串对象的几种形式:

(1)通过new方式如String s = new String("aa")及string.intern()方法

(2)通过字面量的形式如String s = "aa"

(3)字面量+字面量如String s = "b" + "c"

(4)字面量+变量如String s1 = "d"; String s = "e"+s1

对于通过new方式创建的String对象,每次都会在Heap(堆)上创建一个新的实例,但是对于字符串字面量的形式,只有当字符串常量池中不存在相同对象时才会创建。

//关于堆Heap的解释

swift-algorithm-club/Heap at master · raywenderlich/swift-algorithm-club · GitHub

第二种方式不用说,相当于第一种方式中的字面量部分。

第三种和第四种方式会怎样创建字符串对象呢?

关于字符串常量池的问题可以看以下文章:

JDK1.8字符串常量池里存的是String对象还是引用?

翻译:String类的intern()方法:一个初始为空的字符串池,它由类String独自维护。当调用 intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象(注意是常量池中的对象,不是堆中的对象)的引用。 对于任意两个字符串s和t,当且仅当s.equals(t)为true时,s.intern() == t.intern()才为true。所有字面值字符串和字符串赋值常量表达式都使用 intern方法进行操作。

自己用代码举了几个例子:

package com.company;

import com.sun.org.apache.xml.internal.utils.StringToStringTable;

public class Main {
    public static void main(String[] args) {
        String s1="hello";//创建String型引用变量s1,指向字符串常量池中的"hello"字符串。
        String s2=new String("hello");//栈中创建s2引用变量,堆内存中创建"hello"字符串对象,并被s2指向。
        System.out.println(s1 == s2);//false
        String s3="h"+"ello";//"h"和"ello"合成为字符串常量"hello",先在字符串常量池中查找是否已有"hello"字符串对象,已有,不再重新创建对象
        System.out.println(s1 == s3);//true
        String s4="h"+new String("ello");//在堆中创建了"ello"对象,与"h"相加,返回新的字符串对象赋给s4,s4还指向堆中的字符串对象。
        System.out.println(s1==s4);//false
        System.out.println(s2==s4);//false
    }
}
package com.company;

import com.sun.org.apache.xml.internal.utils.StringToStringTable;

public class Main {
    public static void main(String[] args) {
        String string1 = "hello";
        String string2 = new String("hello");
        String string3 = new String("hello");
        System.out.println(string1 == string2.intern());//true
        System.out.println(string2 == string3.intern());//false
    }
}

 记录自己学习java的历程

参考文章:

JDK1.8字符串常量池里存的是String对象还是引用? - 程序员曾奈斯 - 博客园

java 字符串,字符串缓冲区_chen_yuyunfox的专栏-CSDN博客_java 字符串缓存 

String literal pool – iByteCode Technologies 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/708321.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号