- 浏览: 62919 次
- 性别:
- 来自: 成都
文章分类
最新评论
String中intern的方法
首先查看官方API那个的解释:
———————————————————————————————————————
intern
public String intern()
返回字符串对象的规范化表示形式。
一个初始时为空的字符串池,它由类 String 私有地维护。
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
所有字面值字符串和字符串赋值常量表达式都是内部的。
返回:
一个字符串,内容与此字符串相同,但它保证来自字符串池中。
———————————————————————————————————————
尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用”ab”.intern()方法的时候会返回”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用。
可以看下面一个范例:
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 1 String str1 = "a"; 2 String str2 = "b"; 3 String str3 = "ab"; 4 String str4 = str1 + str2; 5 String str5 = new String("ab"); 6 7 System.out.println(str5.equals(str3)); 8 System.out.println(str5 == str3); 9 System.out.println(str5.intern() == str3); 10 System.out.println(str5.intern() == str4);
得到的结果:
true
false
true
false
为什么会得到这样的一个结果呢?我们一步一步的分析。
第一、str5.equals(str3)这个结果为true,不用太多的解释,因为字符串的值的内容相同。
第二、str5 == str3对比的是引用的地址是否相同,由于str5采用new String方式定义的,所以地址引用一定不相等。所以结果为false。
第三、当str5调用intern的时候,会检查字符串池中是否含有该字符串。由于之前定义的str3已经进入字符串池中,所以会得到相同的引用。
第四,当str4 = str1 + str2后,str4的值也为”ab”,但是为什么这个结果会是false呢?先看下面代码:
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 1 String a = new String("ab"); 2 String b = new String("ab"); 3 String c = "ab"; 4 String d = "a" + "b"; 5 String e = "b"; 6 String f = "a" + e; 7 8 System.out.println(b.intern() == a); 9 System.out.println(b.intern() == c); 10 System.out.println(b.intern() == d); 11 System.out.println(b.intern() == f); 12 System.out.println(b.intern() == a.intern());
运行结果:
false
true
true
false
true
由运行结果可以看出来,b.intern() == a和b.intern() == c可知,采用new 创建的字符串对象不进入字符串池,并且通过b.intern() == d和b.intern() == f可知,字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量(如f中的e)则不会进入字符串池中。但是字符串一旦进入字符串池中,就会先查找池中有无此对象。如果有此对象,则让对象引用指向此对象。如果无此对象,则先创建此对象,再让对象引用指向此对象。
当研究到这个地方的时候,突然想起来经常遇到的一个比较经典的Java问题,就是对比equal和==的区别,当时记得老师只是说“==”判断的是“地址”,但是并没说清楚什么时候会有地址相等的情况。现在看来,在定义变量的时候赋值,如果赋值的是静态的字符串,就会执行进入字符串池的操作,如果池中含有该字符串,则返回引用。
执行下面的代码:
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 1 String a = "abc"; 2 String b = "abc"; 3 String c = "a" + "b" + "c"; 4 String d = "a" + "bc"; 5 String e = "ab" + "c"; 6 7 System.out.println(a == b); 8 System.out.println(a == c); 9 System.out.println(a == d); 10 System.out.println(a == e); 11 System.out.println(c == d); 12 System.out.println(c == e);
运行的结果:
true
true
true
true
true
true
运行的结果刚好验证了我刚才的猜想。
***************************************************************
String a = new String("xyz");到底是几个对象?
哈哈,要理解这个,就要知道string类的工作原理。
你知道在java中除了8中基本类型外,其他的都是类对象以及其引用。所以 "xyz "在java中它是一个String对象.对于string类对象来说他的对象值是不能修改的,也就是具有不变性。
看:
String s= "Hello ";
s= "Java ";
String s1= "Hello ";
String s2=new String( "Hello ");
啊,s所引用的string对象不是被修改了吗?之前所说的不变性,去那里了啊?
你别着急,让我告诉你说发生了什么事情:
在jvm的工作过程中,会创建一片的内存空间专门存入string对象。我们把这片内存空间叫做string池。
String s= "Hello ";当jvm看到 "Hello ",在string池创建string对象存储它,并将他的引用返回给s。
s= "Java ",当jvm看到 "Java ",在string池创建新的string对象存储它,再把新建的string对象的引用返回给s。而原先的 "Hello "仍然在string池内。没有消失,他是不能被修改的。
所以我们仅仅是改变了s的引用,而没有改变他所引用的对象,因为string对象的值是不能被修改的。
String s1= "Hello ";jvm首先在string池内里面看找不找到字符串 "Hello ",找到,返回他的引用给s1,否则,创建新的string对象,放到string池里。这里由于s= "Hello "了,对象已经被引用,所以依据规则s和s1都是引用同一个对象。所以 s==s1将返回true。(==,对于非基本类型,是比较两引用是否引用内存中的同一个对象)
String s2=String( "Hello ");jvm首先在string池内里面看找不找到字符串 "Hello ",找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建string对象存储 "Hello ",并将内存上的(不是string池内的)string对象返回给s2。所以s==s2将返回false,不是引用同一个对象。
好现在我们看题目:
String s = new String( "xyz ");
首先在string池内找,找到?不创建string对象,否则创建, 这样就一个string对象
遇到new运算符号了,在内存上创建string对象,并将其返回给s,又一个对象
所以总共是2个对象
例如::
String a=new String("haha");
String b=new String("haha");
String aa="haha";
String aaa="ha"+"ha";
String c="ha";
System.out.println(a==b);
System.out.println(a==aa);
System.out.println(a==aaa);
System.out.println(a==c+"ha");
System.out.println(aa==aaa);
输出结果:false
false
false
false
true
发表评论
-
Eclipse快捷键
2011-11-28 15:19 788Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功 ... -
myDemo
2011-09-23 18:02 0我的demo 文件。 -
我的实现.
2011-09-23 01:26 0我的代码实现... -
mybatis的实现
2011-09-23 00:09 0mybatis -
喊数字出圈的算法
2012-06-08 17:34 1005public static int cycle(int to ... -
JAVA_线程2
2011-09-03 22:46 0线程---程序中单独顺序的流控制.线程本身不运行,只能用于程序 ... -
JAVA_线程
2011-09-03 14:57 399//子线程循环2次,主线程5,接着子又循环2次,主循环5,如此 ... -
Collections集合类的方法进行排序
2011-09-02 22:20 780test.java 写道 public static voi ... -
final关键字
2011-09-02 15:33 677使用final关键字修饰一个变量时,是引用不能变,还是引用的对 ... -
java动态代理
2011-08-29 19:50 0动态代理步骤: 1.创建一个实现接口InvocationHa ... -
JVM中堆和栈的描述
2011-08-21 16:11 922JVM specification对JVM内存的描述: ... -
java复习_异常
2011-09-05 23:09 691**************异常*********** ... -
J2se 基础复习
2011-09-06 14:54 610java是跨平台语言,真正执行的不是2进制码,而是字节码. ... -
Eclipse
2011-09-05 19:48 6371.在window下eclipse中新建一个工程是gbk编码格 ... -
set,Iterator
2011-03-27 00:21 884set和list不一样,因为set是无序的,没有重复对象的集合 ... -
第一次认真写博客
2011-03-26 01:59 701第一次在javaeye认真写自己的博客,决定以后会继续写下去。 ...
相关推荐
本文主要介绍了C++中的字符串类函数原型借鉴,通过自定义的String类来实现字符串的操作。下面将对标题、描述、标签和部分内容进行详细的分析和解释。 标题:C++ String 类函数原型借鉴 C++中的字符串操作是非常...
在这个"链表string类程序"中,我们可以预想它可能涉及到用C++实现链表结构,并结合`std::string`进行字符串的操作。下面将详细介绍`std::string`类以及如何将其与链表相结合。 1. **`std::string` 类基础** `std::...
String类的intern、split方法 String 类的 intern 方法是一个本地方法,定义如下:public native String intern();该方法返回一个字符串对象的内部化引用,由 String 类维护一个初始为空的字符串的对象池,当 ...
关于String类的一些问题 掌握String类的两种实例化方式 掌握String的两种比较操作 深入分析String类两种实例化方式的区别 掌握String的使用特点
在Java编程语言中,`String`类是使用最频繁的类之一,它代表不可变的字符序列。本文将深入解析`String`类的一些常用方法,帮助开发者更好地理解和使用这个核心类。 1. **构造方法** - `String()`:创建一个空字符...
### 正确使用String类的几点注意 在Java编程中,`java.lang.String`类是极为常见的基础数据类型之一,其重要性和应用范围不言而喻。为了更好地理解和使用String类,本文将从几个关键方面入手,探讨如何更加高效、...
#### 一、C++中的String类设计与实现 在本案例中,我们通过自定义一个`String`类来探讨如何在C++中实现字符串类的基本功能,包括构造函数、析构函数、重载运算符以及成员函数等。 #### 二、构造函数与析构函数 1....
在C++编程中,"数据结构学习——我的string类"是一个典型的任务,旨在帮助初学者理解数据结构的基本概念,并通过实现自定义的string类来深化对C++的理解。下面将详细讨论这个主题,以及相关的知识点。 首先,让我们...
### 自定义String类详解 #### 一、引言 在软件开发过程中,字符串处理是非常常见的需求之一。标准库中的`std::string`类为开发者提供了高效且易用的字符串操作功能,但在某些特定场景下,可能需要实现一个自定义的...
通过上面的分析,我们可以看到,String类的字符串是不可变的,而StringBuffer和StringBuilder类的字符串可以被修改。StringBuffer类是线程安全的,而StringBuilder类不是线程安全的。 在选择字符串类时,我们需要...
### String类创建对象问题 #### 一、String 类与常量池、字符串池的基本概念 在 Java 中,`String` 类并不属于八种基本数据类型之一,而是作为一个对象存在。这意味着 `String` 对象默认值为 `null`。尽管如此,`...
String 类的应用场景非常广泛,可以应用于文本处理、数据分析、日志统计等领域。 C++ 的 string 类提供了许多实用的函数和操作符,极大地方便了字符串的处理。掌握 string 类,可以极大提高开发效率和质量。
在Java编程语言中,`String`类是使用最频繁的类之一,它代表不可变的字符序列。在本文中,我们将深入探讨`String`类的一些关键方法,这些方法在日常编程中极为常用,有助于字符串的处理和操作。 1. **构造方法**: ...
### Java中String类详解 #### 引言 在Java编程语言中,`String`类扮演着至关重要的角色,它用于表示字符序列。本文档旨在深入探讨`String`类的特性和功能,帮助开发者更好地理解和应用这一核心类。 #### String类...
标题与描述中提到的知识点是关于C#编程语言中`String`与`string`的区别,以及`string`类型的...通过以上分析,我们可以深入了解C#中`String`与`string`的区别及其使用细节,这对于提高代码质量和程序性能具有重要意义。
标题:“String类方法总结” 描述:“string类方法总结,由毕姥爷精心提炼,被誉为学习String类的必读经典。” **知识点详述:** 在Java编程语言中,`String`类是一个极其重要的类,用于处理文本数据。由于其不可...
通过上述分析,我们可以看到`String`类的设计不仅仅局限于构造函数,还包括了类的整体设计、资源管理策略以及异常处理等多个方面。这不仅有助于我们更好地理解和掌握C++语言的高级特性,也为实际项目开发提供了宝贵...
### String类实现详解 在本篇文章中,我们将深入探讨一个自定义`String`类的实现细节,该类包含了构造函数、析构函数以及各种常用的操作符重载方法。通过具体的代码示例,我们可以更好地理解这些功能如何在C++中被...
通过阅读和分析这些文件,你可以深入理解自定义`String`类的具体实现细节,并可能从中学习到内存管理、面向对象编程以及C++语言特性的实际应用。如果有任何疑问,按照描述中的提示,你可以与作者进行探讨,进一步...
然而,由于这里只给出了文件名,具体实现细节无法提供,以上分析基于对常见自定义String类设计的普遍理解和期望改进的方向。对于深入学习,建议阅读源代码并进行调试,以完全理解作者所做的改进。