`
kejun
  • 浏览: 28334 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java String 对象收藏

    博客分类:
  • J2SE
阅读更多
起因:
String a="Hello World!";
String b="Hello World!";
a==b?   a和b是否相等 ? 为什么?

String a=new String("Hello World!");
String b="Hello World!";
a==b?   a和b是否相等 ? 为什么?
解释:
1. 首先String不属于8种基本数据类型,String是一个对象。
因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。 

2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;

3. String str="kvill";和String str=new String (“kvill”);的区别: 
在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。 
常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的
一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。 
看例1: 
String s0="kvill"; 
String s1="kvill"; 
String s2="kv" + "ill"; 
System.out.println( s0==s1 ); 
System.out.println( s0==s2 ); 
结果为: 
true 
true 
首先,我们要知道Java会确保一个字符串常量只有一个拷贝。 
因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以
s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连
接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。所以我们得出s0==s1==s2; 

用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String()
创建的字符串不放入常量池中,它们有自己的地址空间。 

看例2: 
String s0="kvill"; 
String s1=new String("kvill"); 
String s2="kv"+ new String("ill"); 
System.out.println( s0==s1 ); 
System.out.println( s0==s2 ); 
System.out.println( s1==s2 ); 
结果为: 
false 
false 
false 
例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创
建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译
期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。 

4. String.intern(): 
再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了。 

例3: 
String s0= "kvill"; 
String s1=new String("kvill"); 
String s2=new String("kvill"); 
System.out.println( s0==s1 ); 
System.out.println( “**********” ); 
s1.intern();
s2=s2.intern(); //把常量池中"kvill"的引用赋给s2 
System.out.println( s0==s1); 
System.out.println( s0==s1.intern() ); 
System.out.println( s0==s2 ); 
结果为: 
false 
********** 
false //虽然执行了s1.intern(),但它的返回值没有赋给s1 
true //说明s1.intern()返回的是常量池中”kvill”的引用 
true

最后我再破除一个错误的理解: 
有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局Strin
g表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的: 

看例4: 
String s1=new String("kvill"); 
String s2=s1.intern(); 
System.out.println( s1==s1.intern() ); 
System.out.println( s1+" "+s2 ); 
System.out.println( s2==s1.intern() ); 
结果: 
false 
kvill kvill 
true 
在这个类中我们没有声名一个"kvill"常量,所以s1.intern()同new String("kvill")是不同的,当我们调用s1.intern()后就在常量池中新添加了一个"kvill"常量,原来的不在常量池中的"kvill"仍然存在,也就不是“将自己的地址注册到常量池中”了。 
s1==s1.intern()为false说明原来的“kvill”仍然存在; 
s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。 

5. 关于equals()和==: 

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。 

6. 关于String是不可变的 

这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:
String str=”kv”+”ill”+” “+”ans”; 
就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。
7.注意
    看下面例子:
 public class StringTest
{
   
     public static void main(String[] args)
     {
         String str1 = "hello";
         String str2 = "hel";
         str2 = str2 + "lo";   
         System.out.println("str1 == str2 :" + (str1 == str2));
     }
}

实际会打出false
为什么呢,关键就在于str2=str2+"lo"是不能能编译期就确定的
str1是在内存池没错,但str2不是~
用反编译工具反编译一下class文件就会发现
str2 =str2+"lo";
实际上是:
str2 = (new StringBuilder()).append(str2).append("lo").toString();
显然,str2是new出来的(不信去看看StringBuilder的源代码)
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    gson 使用Gson将Java对象转换为JSON

    Gson是Google的一个开源项目,可以将Java对象转换成JSON,也可能将JSON转换成Java对象。 Gson里最重要的对象有2个Gson 和 GsonBuilder Gson有2个最基本的方法 1) toJson() – 转换java 对象到JSON 2) from...

    java C++ 书籍收藏

    - String的intern方法:返回字符串常量池中所持的该字符串对象的引用,如果常量池中没有对应的字符串,则将此字符串添加到常量池。 2. 单例模式 - 单例模式确保一个类只有一个实例,并提供一个全局访问点。 - ...

    精品资料(2021-2022年收藏)面向对象技术Java期末复习试卷三.doc

    面向对象技术是编程领域中的核心概念,特别是在Java编程语言中。本资料主要涵盖了Java面向对象的一些基础和关键知识点,适合期末复习使用。 1. **Java源文件命名规则**: - 在Java中,源文件(`.java`)的命名应当...

    精品专题(2021-2022年收藏)Java语言与面向对象程序设计在线作业F答案.docx

    《Java语言与面向对象程序设计》精品专题详解 Java语言是一种广泛应用于各类软件开发的高级编程语言,以其面向对象的特性而闻名。本专题主要涵盖了Java的基础知识,包括类的声明、对象的创建、成员变量的声明以及...

    精品资料(2021-2022年收藏)面向对象技术Java期末复习试卷五.doc

    【Java面向对象编程】 在Java编程中,面向对象技术是核心概念之一,它基于对象、类、继承、封装、多态等原则。本题考察了这些面向对象的关键知识点。 1. **接口(Interface)**: - 接口在Java中是一种完全抽象的...

    java文件打开保存代码收藏

    - `File f`:用来存储文件对象。 - `JFrame frm`:通常用于存储父窗口,这里可能未被正确初始化。 - `JFileChooser fc`:用于打开文件选择对话框。 - `int flag`:用来标记文件操作的状态。 ### 4. 创建GUI组件 ...

    java基础面试题及答案整合收藏版

    - **概念**:类是对象的抽象描述,而对象则是类的具体实例。 - **作用**:类定义了对象的属性和行为,即数据成员(属性)和成员方法(行为)。 - **实例化**:通过关键字 `new` 创建类的实例,即对象。 #### 1.2 ...

    Java时间日期处理相关文档收藏

    String formattedTomorrow = tomorrow.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); ``` 以上就是Java时间日期处理的一些核心概念和常见操作。理解并熟练掌握这些知识点对于日常开发至关重要,因为时间日期...

    Java串口通信详解收藏

    - **配置串口参数**:例如波特率、数据位、停止位等,可以通过`SerialPort`对象的相关方法进行配置。 - **打开和关闭串口**:通过`SerialPort.openPort()`和`SerialPort.closePort()`方法控制串口的打开和关闭。 ##...

    Java文件操作大全(绝对的经典,值得收藏!)

    String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); fr.close(); ``` 这里通过`FileReader`打开文件,然后用`BufferedReader`进行逐行读取,直到文件结束。 ...

    Java学生成绩管理系统源代码

    例如,在主方法中创建了一个`BufferedReader`对象来从标准输入流(即键盘输入)读取用户的选择: ```java BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); ``` 当用户需要输入特定信息...

    精品专题(2021-2022年收藏)Java程序设计期末试卷附答案.doc

    11. **对象创建与回收**:Java的垃圾回收机制自动回收不再使用的对象,不需要关键字`free`。选项1错误。 12. **对象赋值**:对象赋值实际上是引用复制,而不是复制对象本身。选项2错误。 13. **构造函数**:每个类...

    java面试宝典价值巨大值得收藏.pdf

    Java是一种广泛使用的面向对象的编程语言,其语法严谨且具有丰富的特性。对于Java开发者来说,理解和掌握这些知识点是至关重要的,特别是在面试过程中,这些问题经常会被问到。以下是对标题和描述中提到的一些Java...

    精品专题(2021-2022年收藏)java周总结.doc

    Java是一种广泛使用的面向对象编程语言,其核心理念是“万物皆对象”。面向对象编程(OOP)相较于面向过程编程,更注重数据和操作数据的方法,它以对象作为基本的编程单元,强调数据封装和模块化。 面向对象的主要...

    2021-2022年收藏的精品资料软件工程师Java七步创建JDBC连接数据库程序方法教程.docx

    Java中的JDBC(Java Database Connectivity)是用于连接Java应用程序与各种数据库的标准接口。通过使用JDBC,开发者可以编写代码来创建、查询、更新和管理数据库。以下是对标题和描述中所述知识点的详细解释: 1. *...

    DVD.zip_java编写一个dvd

    在Java中实现这样的系统,开发者会运用到面向对象编程的概念,如类、对象、接口和继承,来构建模块化的代码结构。 首先,我们需要创建一个`DVD`类,这个类可能包含属性如DVD的标题、导演、主演、时长、类型等。这些...

    Java基础常用面试题

    - String是不可变对象,适用于不可修改的字符串操作,线程安全。 - StringBuilder是可变对象,不保证线程安全,性能优于String,适用于单线程环境。 - StringBuffer也是可变对象,保证线程安全,但性能略低于...

    java正则表达式帮助文档(全)

    在Java中,正则表达式通过`java.util.regex`包来实现,提供了`Pattern`、`Matcher`和`String`类的相关方法来支持正则表达式的操作。 1. **正则表达式基础** - **字符类**:如`[abc]`,匹配任何一个括号内的字符。 ...

Global site tag (gtag.js) - Google Analytics