java中String类intern()方法探索

想到什么写什么,会有点乱,意思理解就行

首先我们创建两个字符串对象,如下:

String a = new String("hx");
String b = new String("h")+new String("x");

通过new关键字创建字符串对象时,会同时在堆和常量池中生成两个对象,比如说上面的第一条语句产生两个内容均为"hx"的对象,一个在堆中,一个在常量池中,a引用的是堆中的对象,内容是"hx";上面第二条语句产生五个对象,其中两个匿名对象的内容分别是"h"和"x",对应的,常量池中也会生成两个对象,内容分别是"h"和"x",还有一个对象是b引用的,在堆中,内容是"hx";

还有一种创建字符串对象的方法,就是直接赋值,如下:

String c = "hx";

这里,c引用的对象直接放在了常量池中

(常量池中内容相同的字符串对象,地址一定是相同的,而堆中不同的对象,地址一定不同)

理解上面的内容,然后继续往下看。

String类中intern()方法其实也是一个对象的引用(个人理解),引用的对象在常量池中

比如先通过new关键字创建字符串对象String s = new String("hx"),变量s引用这个对象,s.intern()方法就是检查常量池中有没有一个内容相同的对象

(这里是有的,因为之前说过,通过new关键字会同时创建两个内容相同的对象,一个在堆中,一个在常量池中),

若有,则s.intern()引用那个对象,此时(s == s.intern())是false,因为s和s.intern()引用的是两个不同的对象,只是内容相同,地址不同,自然不可能相等;

若没有(这种情况我也可以举个例子,String s = new String("h")+new String("x") ,此时常量池中只有两个内容分别为"h"和"x"的对象),则会在常量池中创建一个对象的引用,指向s引用的那个对象(这也是jdk1.7及以后版本与jdk1.6及以前版本的差别,我只探讨最新版本,不多说),说白了就是调用s.intern()方法后,在常量池中出现了一个引用,引用堆中s引用的那个对象(相当于绕了个圈,节省了内存,但时间开销更大),此时(s.intern() ==  s)是true,理由是两者引用的是同一个对象,地址相同,若此时出现这样一条语句String m ="hx",那么(m == s)或者(m == s.intern())就都是true了,因为两者引用了同一个对象,之前说过,常量池中内容相同的对象,地址一定相同,因为之前s.intern()首先在常量池中占了个坑,以后常量池中内容为"hx"的都是引用s.intern()引用的那个对象。

下面通过实例说话

String a = new String("hx");
System.out.println("1."+(a==a.intern()));

false

String a = new String("h")+new String("x");a.intern();String b = "hx";System.out.println("2."+(a==a.intern()));System.out.println("3."+(b==a));
 

true

true

String a = new String("hx");
a.intern();
String b ="hx";
System.out.println("4."+(a==b));
System.out.println("5."+(b==a.intern()));

false

true

String a = new String("hx");
String b = "hx";
a.intern();
System.out.println("6."+(a==a.intern()));
System.out.println("7."+(b==a.intern()));

false

true

是否有些头绪了?总之常量池中内容相同的,地址一定相同,谁第一个占坑了(两种占坑方式:intern()方法和直接声明常量,例如String t = "abc"),以后和它内容相同的都引用这个坑没差,重点要理解intern()方法引用的是哪个对象,地址在堆中还是在常量池中,还有一点,intern()方法一定是引用某个对象,绝不会自己创建一个对象然后引用的。

最后还有两种情况

String a = "h";String b = "hx"
String c = a+"x";
System.out.println(b==c);

结果是false

但如果改一下子,第一条语句加个关键字final

final String a = "h";
    String b = "hx";
    String c = a+"x";
    System.out.println(b==c);

结果是true

以下纯属个人理解:

首先出现这种情况无非就是引用的对象不相同,那第一种情况就是,b引用的对象在常量池中,c引用的对象在堆中;

第二种情况是,b和c引用的对象为同一个,均在常量池中。

就是final的问题,有这个关键字时,String c = a + "x";在编译时就那啥(描述不来,凑合着理解理解)产生了一个常量放在常量池中,然后发现已经有一个内容相同的了,就直接引用那个的了;没有这个关键字时,String c = a+"x"在运行时才产生结果,这个结果就只能是一个对象了,放在堆中,无法放入常量池中,因为常量池的内容在编译后就确定了,所以c == a自然就是false;

然后还有就是为什么一个在编译时就产生结果,一个就在运行时才能产生结果,这得问问final这个关键字了,我也不是很懂..

时间: 2024-12-12 01:39:34

java中String类intern()方法探索的相关文章

【转载】Java中String类的方法及说明

转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一.构造函数     String(byte[ ] bytes):通过byte数组构造字符串对象.     String(char[ ] value):通过char数组构造字符串对象.     String(Sting original):构造一个original的副本.即:拷贝一个original.     String(Strin

Java中String类的方法及说明

String : 字符串类型 一.构造函数     String(byte[ ] bytes):通过byte数组构造字符串对象.     String(char[ ] value):通过char数组构造字符串对象.     String(Sting original):构造一个original的副本.即:拷贝一个original.     String(StringBuffer buffer):通过StringBuffer数组构造字符串对象.  例如:      byte[] b = {'a',

java中string类的方法和加密程序

String.equals()方法: 是对String对象所封装的字符串内容进行比较,也就是说,如果两个String对象所封装的字符串内容相同(包括大小写相同),则equals()方法将返回true. String类的length(),char(),getChar(),replace(),toUpperCase(),tolowerCase(),trim(),tocharArray()使用说明 Length()求字符串长度 Char()获取给定的index处的字符 getChar()字符转换成数组

Java中String类与Integer类的几个方法

计算诸如-123,456,789 + 123,123的值 import java.math.BigInteger; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner cin = new Scanner(System.in); String str1, str2; BigInteger a, b; while(cin.hasNext()){ str1 = cin.

Java中String类学习总结

java中String类的使用频率非常高,本人在学习此模块时,认为下列几点知识值得注意: 一.String是不可变对象 java.lang.String类使用了final修饰,不能被继承.Java程序中的所有字面值,即双引号括起的字符串,如"abc",都是作为String类的实例实现的.String是常量,其对象一旦构造就不能再被改变.换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容.而最

深入分析Java的String类的方法与特点

字符串是任何编程语言都必须支持的变量类型,有些编程语言是直接提供了原生的变量类型,有些编程语言则使用语法特性以 SDK 的形式提供支持.在Java编程平台中,对字符串的支持使用了后者的形式,就是通过在 JDK中提供一个名为String的类,对应字符串这个变量类型. 源码分析 既然JDK中的String类对应了字符串变量类型,为了熟练地掌握Java中字符串相关的技能,我们必须深入地分析和研究一下这个类.编码界有一句名言叫做 "源码面前,了无秘密",因此,我们第一步就是来看看String类

hadoop中Text类 与 java中String类的区别

hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念: 字符集: 是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.例如 unicode就是一个字符集,它的目标是涵盖世界上所有国家的文字和符号: 字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对.即在符号集

Java中Integer类的方法

字段摘要 static int MAX_VALUE              保持 int 类型的最大值的常量可取的值为 231-1. static int MIN_VALUE              保持 int 类型的最小值的常量可取的值为 -231. static int SIZE              以二进制补码形式表示 int 值的位数. static Class<Integer> TYPE              表示基本类型 int 的 Class 实例. 构造方法摘要

java中String类小结

构建一个字符串 1.用字符串直接量: String message = new String("Welcome to java"); 2.用字符串直接量: String message = "Welcome to java"; 3.用字符数组 Char[] charArray = {'m', 'y'}; String message = new String(charArray); 不可变字符与限定字符串 String对象是不可变的,内容不能改变 java虚拟机为了