- public class StringTest {
- public static void main(String[] args) {
- String str = new String("abc"); //语句(1)
- String str1 = "abc";//语句(2)
- String str2 = new String("abc");//语句(3)
- System.out.println(str == str1);//语句(4)
- System.out.println(str == str2);//语句(5)
- System.out.println(str1 == str2);//语句(6)
- System.out.println(str == str.intern());//语句(7)
- System.out.println(str1 == str1.intern());//语句(8)
- System.out.println(str.intern() == str2.intern());//语句(9)
- String hello = "hello";//语句(10)
- String hel = "hel";//语句(11)
- String lo = "lo";//语句(12)
- System.out.println(hello == "hel" + "lo");//语句(13)
- System.out.println(hello == "hel" + lo);//语句(14)
- }
- }
public class StringTest { public static void main(String[] args) { String str = new String("abc"); //语句(1) String str1 = "abc";//语句(2) String str2 = new String("abc");//语句(3) System.out.println(str == str1);//语句(4) System.out.println(str == str2);//语句(5) System.out.println(str1 == str2);//语句(6) System.out.println(str == str.intern());//语句(7) System.out.println(str1 == str1.intern());//语句(8) System.out.println(str.intern() == str2.intern());//语句(9) String hello = "hello";//语句(10) String hel = "hel";//语句(11) String lo = "lo";//语句(12) System.out.println(hello == "hel" + "lo");//语句(13) System.out.println(hello == "hel" + lo);//语句(14) } }
问题1:当执行完语句(1)时,在内存里面生成几个对象?它们是什么?在什么地方?
解答:当执行完语句(1)时,内存里面生成2个对象,它们的内容分别都是abc,注意:str不是对象,它是对象的地址,它叫做引用(reference),str指向new...生成的对象。换句话说,在java里面,当我们定义一个类的变量(如:String str;),它永远都是引用,不是对象。那么什么是对象呢?当我们用关键字new时,它生成出来的东西叫做对象。为什么是两个对象呢?首先它生成一个对象是abc,这个abc对象在什么地方呢?它在一个叫String Pool的字符串池里面,只有String有这样一个String池。String池是一个什么概念呢?我们知道,String类是一个不可变的类,一但它的内容确定,它就不能去更改了。当你去生成一个字符串对象的时候,它的执行流程是这样的:它首先在你的String Pool里面去找,看有没有一个内容为abc的对象存在,因为tring str = new String("abc")它是main方法的第一个语句,那么在刚开始执行的时候,String Pool里面是没有对象的。它发现String Pool里面没有abc这个对象,那么它首先把new String("abc")的括号里面的abc对象放到String Pool里面,接下来它执行new ...这行语句, 执行String的构造方法。我们知道new它生成一个对象,这个对象在什么地方呢?在java的堆里面。我们知道java的内存分为2部分,一个叫栈(Stack),一个叫堆(Heap)。那么new String("abc")时,它在堆(Heap)里面,生成一个内容为abc的这样一个对象。这样就造成了在String Pool里面一个叫abc的对象,堆里面也有一个叫abc的对象。我们这里用的是public String(String original)这个构造方法。jdk api是这样叙述的:
Initializes a newly created String object so that is represents the same sequence of characters as the argument;in other words,the newly created string is a copy of the argument string.Unless an explicit copy of original is needed,use of this constructor is unnecessary since Strings are immutable.(翻译:初始化一个新创建的String对象,表示一个与该参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的一个副本。由于 String 是不可变的,不必使用该构造方法,除非需要original的显式副本。)
问题2:当执行完语句(2)时,在内存里面一共有几个对象?它们是什么?在什么地方?
解答:当执行完语句(2)时,内存里面一个新的对象都没有生成。为什么这么说?当我们定义语句(2)的时候,如果我们用字符串的常量值(字面值)给str1赋值的话,那么首先java还是从String Pool里面去查找没有有内容为abc的这样一个对象存在,我们发现当我们执行完语句(1)的时候,StringPool里面已经存在了内容为abc的对象,那么就不会再在tring Pool里面去生成内容为abc的字符串对象了。而是会使用已经存在String Pool里面的内容为abc的字符串对象,并且会将str2这个引用指向String Pool里面的内容为abc的字符串对象,str2存放的是String Pool里面的内容为abc的字符串对像的地址。也就是说当你使用String str2 = "abc",即使用字符串常量("abc")给定义的引用(str2)赋值的话,那么它首先是在String Pool里面去找有没有内容为abc的字符串对象存在,如果有的话,就不用创建新的对象,直接引用String Pool里面已经存在的对象;如果没有的话,就在 String Pool里面去创建一个新的对象,接着将引用指向这个新创建的对象。所以,当执行完语句(2)时内存里面一共有2个对象,它们的内容分别都是abc, 在String Pool里面一个内容abc的对象,在堆里面有一个内容为abc的对象。
问题3:当执行完语句(3)时,在内存里面一共有几个对象?它们是什么?在什么地方?
解答:执行完语句(3)时,执行过程是这样的:它首先在String Pool里面去查找有没有内容为abc的字符串对象存在,发现有这个对象存在,它就不去创建 一个新的对象。接着执行new...,只要在java里面有关键字new存在,就表示它生成一个新的对象,new多少次,就生成多少个对象,而且新生成的对象都是在堆里面,所以它会在堆里面生成一个内容为abc的对象,并且将它的地址赋给了引用str2,str2就指向刚在堆里面生成的内容为abc的对象。所以,当执行完语句(3)时,内存里面一共有3个对象,其中包含了一个在String Pool里面内容为abc的字符串对象,另外在堆里面包含了两个内容为abc的字符串对象。
问题4:当执行完语句(4)(5)(6)后,它们的结果分别是什么?
解答:在java里面,对象用"=="永远比较的是两个对象的内存地址,换句话说,是比较"=="左右两边的两个引用是否指向同一个对象。对于java里面的8种原生数据类型来说,"=="比较的是它们的字面值是不是一样的;对应用类型来说,比较的是它们的内存地址是不是一样的。在语句(1)(2)(3)中,由于str、str1、str2指向不同的对象,它们的内存地址就不一样,因此可以说当执行完语句(4)(5)(6),它们返回的结果都是false。
问题5:当执行完语句(7)(8)(9)后,它们的结果分别是什么?
解答:jdk api里对方法public String intern()是这样叙述的:
Return a canonical representation for the string object.(翻译:返回字符串对象的标准化表示形式。)A pool of strings,initially empty,is maintained privately by the class String.(翻译:一个初始时为空的字符串池,它由类 String 私有地维护。) When the intern method is invoked,if the pool already contains a string equeal to this String objectas determined by the equals(Object) method,then the string from the pool is returned.Otherwise,this String object is added to the pool and a reference to the String object is returned.(翻译:当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。)If follows that for any two strings s and t,s.intern() == t.intern() is true if and only if s.equals(t) is true.(翻译:它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。)All literal strings and string-valued consrant expressions are interned.String literals and defined in §3.10.5 of the Java Language Specification.(翻译:所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java Language Specification》的 §3.10.5 中已定义。) Returns:a string that has the same contents as this string,but is guaranteed ro be from a pool of unique strings. (翻译:返回一个字符串,内容与此字符串相同,但它保证来自字符串池中。) 当执行语句(7)时,首先,str这个对象指向的是堆中第一次new...生成的对象,根据jdk的api叙述,当调用 intern 方法时,如果String Pool已经包含一个等于此 String 对象的字符串(该对象由equals(Object)方法确定),则返回String Pool中的字符串对象的内存地址。因为String Pool中有内容为abc的对象,所以str.intern()返回的是String Pool中的内容为abc的字符串对象的内存地址,即是str1。而str==str1为false,所以,str == str.intern() 为false,即是语句(7)结果为false。而对于str1.intern(),它还是会首先检查String Pool中是否有内容为abc的对象,发现有,则将String Pool中内容为abc的对象的地址赋给str1.intern()方法的返回值,即str1.intern()的结果为str1。所以,str1 == str1.intern()的结果为true,,即是语句(8)结果为true。对于str.intern(),它首先检查String Pool中是否有内容为abc的对象,发现有,则将String Pool中内容为abc的对象的赋给str.intern()方法的返回值,即str.intern()的结果为str1。对于st2r.intern(),首先检查String Pool中是否有内容为abc的对象,发现有,则将String Pool中内容为abc的对象的地址赋给str2.intern()方法的返回值,即str2.intern()的结果为str1。所以,str.intern() == str2.intern()的结果为true,,即是语句(9)结果为true。因此,当执行完语句(7)(8)(9)后,它们的结果分别是false、true、true。
问题6:当执行完语句(13)(14)后,它们的结果分别是什么?
解答:执行完语句(13)结果为true,执行完语句(14)结果为false。分析:对于hello == "hel" + "lo",hello指向的是String Pool里面的内容为hello的字符串对象,对于"hel" + "lo",当"+"两边都是字面值(字符串常量)的时候,在执行完"+"之后,它接着去判断String Pool里面有没有内容为hello的字符串对象存在,有的话就直接返回String Pool里面的内容为hello的字符串对象的内存地址,所以,hello == "hel" + "lo"结果为true;对于hello == "hel" + lo,lo不是字面值,当"+"两边有一个不是字面值(字符串常量)的时候,那么"+"操作后又会在堆里面生成一个新的对象,也就是说hello的引用是指向String Pool里面的内容为hello的字符串对象,"hel" + lo的结果是返回在堆里面生成一个新的对象,一个在String Pool里面,一个在堆里面,当然为false了。
发表评论
-
网络游戏同步的原理
2011-09-22 20:01 826不知道大家是否碰到过这种情况,当某个玩家发出一个火球,这个火球 ... -
java中的io系统详解
2010-09-16 23:21 889Java 流在处理上分为字符流和字节流。字符流处理的单元为 ... -
java中的日期处理类总结
2010-08-08 20:35 862java中的日期处理类总结:Date/Calendar/Gre ... -
体验J2SE 1.5新特性之增强For循环
2010-04-08 14:49 829J2SE 1.5提供了另一种形 ... -
XPath
2010-03-22 17:52 1626XPath 简介 XPath 是一门 ... -
通过Singleton单例模式,理解Java的类加载
2010-03-22 16:26 1107通过Singleton单例模式,理解Java的类加载----- ... -
全面总结Java泛型
2009-10-25 12:19 768虽然Scala创始人Martin Odersky说当年正是因为 ... -
理解java String
2009-10-20 15:07 616要理解 java中String的运 ... -
Java中"equals"和"=="的区别
2009-10-20 14:01 663一句话概括:==比较的 ... -
Java代码编写的30条建议
2009-05-14 22:21 752(1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母 ... -
深入了解Java泛型(三) -- 泛型方法
2009-05-07 09:51 1849前面提到的都是与类的泛型化相关的话题,不过方法也可以从泛型中受 ... -
深入了解Java泛型(二) -- 泛型列表与数组
2009-05-07 09:48 1025记得以前面试的时候曾 ... -
深入了解Java泛型(一) -- 泛型与原生态类型
2009-05-07 09:45 1223Java1.5引入了泛型之后, ... -
正则表达式入门
2009-05-07 09:16 614元字符: /b 代表着单词 ...
相关推荐
以下是对文档中提到的四个字符串相关函数的详细说明: 1. **strcpy()**:这个函数用于拷贝一个字符串到另一个字符串。在示例中,`pszValue` 的值被复制到 `a` 中。`strcpy()` 需要谨慎使用,因为它不检查目标字符串...
本篇文章将详细介绍一下三个重要的字符串相关函数:`strchr`、`strstr`以及`strtok`。 1. `strchr`函数: `strchr`函数用于在一个字符串中查找指定字符首次出现的位置。函数原型为`char *strchr(const char *str, ...
### JavaScript中字符串相关常用的使用方法总结 #### 一、引言 JavaScript作为一种广泛使用的脚本语言,被大量应用于Web开发之中。其中,字符串处理是非常重要的一个方面,涉及到数据的读取、修改、拼接等操作。...
### Java中的字符串相关处理 #### 引言 在Java编程语言中,字符串处理是一个核心且广泛使用的领域。不同于其他编程语言将字符串视为字符数组,Java将字符串视为`String`类型对象,这一设计使得字符串处理更加高效...
TIA 博途中字符串转换相关指令的使用方法是指在 Siemens SIMATIC TIA Portal 中使用的字符串转换相关指令,包括移动和转换字符串指令、字符串和数值相互进行转换指令等。 1. 移动和转换字符串指令 移动和转换字符...
例如,如果你有一个URL字符串`http://www.pudn.com/downloads123/ebooks/xxx.zip`,你可以用`^http:\/\/www\.pudn\.com`这个正则表达式来截取字符串中与网址相关的部分。匹配结果就是`http://www.pudn.com`。 2. RF...
字符串相关的函数是任何编程语言中不可或缺的一部分,它们提供了对字符串的各种操作。在这个主题中,我们聚焦于一个自定义实现的字符串函数库,它包括了字符串的复制、查找、对比和连接等基本操作。下面将详细讨论...
在Java编程语言中,字符串处理是一项常见的任务,特别是在解析、分析或操作文本数据时。本篇文章将深入探讨如何从字符串中提取括号内的内容...理解并熟练运用这些工具,能帮助开发者更有效地处理各种字符串相关的任务。
在VB(Visual Basic)编程中,处理字符串是常见的任务之一,其中包括将一个长字符串拆分成多个子字符串。这个过程通常称为“字符串拆分”或“分隔字符串”。在这个主题中,我们将深入探讨VB中如何实现这一操作,以及...
从键盘输入一串由数字组成的字符串,例如“234567910”,设计一个高效算法,输出字符串中的升序序列,该升序序列中的数字要么是差值为1的等差序列,要么只允许有一对相邻的数字差值为2,此时将该漏掉的数字找到并...
在Java编程语言中,字符串处理是一项基础且重要的任务。标题提到的"Java检索字符串中是否存在某字符",实际上涉及到字符串的查找...通过学习和理解这些算法,开发者能够更好地处理字符串相关的复杂问题,提高程序性能。
在本实例"实例76_字符串相关_自动填充"中,我们将深入探讨字符串的自动填充技术,它在多种场景下都非常实用,比如格式化输出、生成模板文本等。 首先,让我们了解什么是字符串自动填充。在编程中,自动填充通常指的...
这些函数在实际开发中非常有用,可以帮助开发者快速实现字符串相关的功能。 1. StrComp 函数:用于比较两个字符串,返回一个整数值,表示字符串之间的比较结果。StrComp 函数有三个参数,分别是两个要比较的字符串...
本文将详细讲解如何使用LabVIEW实现十六进制字符串到普通字符串(通常指的是ASCII编码的字符字符串)的转换过程,并探讨相关的编程概念和技术。 首先,我们需要了解LabVIEW的数据类型。在LabVIEW中,字符串是由字符...
### 字符串的比较 #### 一、基本概念 在计算机科学中,字符串是比较常见的数据类型之一,用于处理文本信息。对于字符串的操作包括但不...了解这些方法的工作原理有助于在实际编程中更高效地处理字符串相关的任务。
在IT领域,字符串处理是一项基础且重要的任务,尤其是在编程语言如C#中。"统计字符串中子字符串出现的次数,并返回"是一个常见的需求,广泛应用于文本分析、数据挖掘以及日志处理等多个场景。本篇文章将深入探讨如何...
这些函数可以截取和修改字符串的值,转换和手机字符串相关信息,以及执行 SOUNDEX 分析。在本文中,我们将详细介绍这些函数的用法和示例。 1. 截取字符串的值 T-SQL 提供了多种截取字符串的方法,包括 LEFT、RIGHT...
### MFC字符串CString操作用法详解 #### 一、引言 Microsoft Foundation Classes (MFC) 是一套由微软开发的类库,它...在实际开发过程中,熟练掌握这些函数的使用方法,能够帮助我们更加高效地完成字符串相关的任务。