`
369540808
  • 浏览: 197139 次
文章分类
社区版块
存档分类
最新评论

Java基础之010-深入理解Java的String类

 
阅读更多

Java基础之010-深入理解Java的String类

老帅

1. 首先String不属于8种基本数据类型,String是一个类

  因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

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

  3. String对象实例化

String str=”kvill”;
String str=new String (“kvill”);的区别:

  在这里,我们引入常量池这个简单的概念。常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
关于常量池的详细介绍,请查阅我的另外一篇文章
Java堆、栈和常量池

  看例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
  
  5. 关于equals()和==:

  这个equals()对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;

而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

  6.String和StringBuffer的区别
某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,如在以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:

String S1 = “This is only a” + “ simple” + “ test”;

StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 String S1 = “This is only a” + “ simple” + “test”; 其实就是: String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。

但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: String S2 = “This is only a”; String S3 = “ simple”; String S4 = “ test”; String S1 = S2 +S3 + S4; 这时候 JVM 会规规矩矩的按照原来的方式去做。


7. 创建了几个对象

7.1 这个方法创建了几个对象

String s = new String( "xyz ");
这个语句创建了几个对象?可能是一个,因为常量池中可能已经存在“xyz”这个对象了(编译器创建),所以这个语句不会再在常量池中创建了,只在堆里创建一个对象(运行期创建)。如果常量池中不存在“xyz”,则会创建两个。

7.2 String s = "a" + "b";创建了几个对象

下面简单证明我的推断,首先编译这个类:

public class Test { 
private String s = "ab"; 
}

复制class文件备用,然后修改为

public class Test { 
private String s = "a" + "b"; 
}

再次编译,用ue之类的文本编辑器打开,察看二进制内容,可以发现,两个class文件完全一致,连一个字节都不差.

ok,真相大白了.根本不存在运行期的处理String b = "a" + "b";这样的代码的问题,编译时就直接优化掉了。

也就是说常量池中不会生成三个常量:b1="a", b2="b", b="ab",只会生成 一个b="ab"

8、String是不可变

String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable).
分享到:
评论

相关推荐

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-010-Java语言概述-Java的工作原理-JVM的产生.mp4 北京动力节点-Java编程零基础教程-011-Java语言概述-Java的工作原理-源文件及字节码文件.mp4 北京动力节点-Java编程零基础教程-...

    深入了解java 中的String

    深入了解java 中的String 1、String类是final的,不可被继承。public final class String。 2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[]; 然后打开String类的API文档,...

    深入理解JavaString#intern()内存模型Ja

    深入理解JavaString#intern()内存模型Java开发Java经验技巧共4页.pdf.zip

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

     作者以易于理解的方式深入揭示了java虚拟机的内部工作原理,深入理解这些内容,将对读者更快速地编写更高效的程序大有裨益!  本书共分20章,第1-4章解释了java虚拟机的体系结构,包括java栈、堆、方法区、执行...

    深入理解 Java String#intern() 内存模型.docx

    深入理解 Java String#intern() 内存模型.docx

    【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承、封装、多态的实现原理 容器 Java集合类总结 Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理 Java集合详解2:Queue和...

    深入理解Java:String

    按照官方的说法:Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。 JVM主要管理两种类型内存:堆和非堆,堆内存(HeapMemory)是在Java虚拟机启动时创建,非堆内存(Non-heap ...

    java String的深入理解

    主要介绍了java String的深入理解的相关资料,希望通过本文大家能理解String的用法,需要的朋友可以参考下

    深入理解JVM实战篇-String类1

    A2:当一个String实例调 用 intern() 方法时,Java查找常量池中是否有相同Unicode 的字符串常量,如果有,则返回其的引用,如果没有,则在

    JAVA基础课程讲义

    字符串(java.lang.String类)的使用 90 字符串相等的判断 92 思考作业 93 上机作业 94 第四章 异常机制 95 导引问题 95 异常(Exception)的概念 96 异常分类 96 Error 97 Error和Exception的区别 97 Exception 97 ...

    Java面试题-基础和集合.docx

    这些内容不仅有助于面试者在面试中展现自己的深厚技术功底,还可以帮助读者更深入地理解Java编程语言的内部机制和设计原理。 总的来说,该文件提供了一份全面的Java面试准备指南,涵盖了从基础知识到高级概念的各个...

    对String的深入理解

    语句声明一个类A的引用变量aa[我常常称之为句柄],而对象一般通过new创建。所以题目中s仅仅是一个引用变量,它不是对象。[ref 句柄、引用与对象] 二、Java中所有的字符串文字[字符串常量]都是一个String的对象。有...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ Java面试题08.String.mp4 │ Java面试题09.讲一下java中的集合.mp4 │ Java面试题10.ArrayList LinkedList.mp4 │ Java面试题11.HashMap和HashTable的区别.mp4 │ Java面试题12.实现一个拷贝文件的类使用字节流...

    动力节点Java基础301集_史上最全的Java基础教程

    2:讲集合时先从数组扩容讲起,过度到集合,确实不错,深入浅出比较容易理解。 3:String创建几个对象,这个可以说全网最牛,不过例子举的有点猥琐,总是讲小哥哥与小姐姐的故事。 4: 源码分析分析讲的特别到位,尤其...

    【大厂面试题总结】JavaSE面试题总结详细教程

    深入理解Java的反射机制 深入理解Java异常体系 谈谈NIO的理解 谈一谈对JUC的理解 ArrayList的底层原理 HashMap的底层原理 iava单例模式详解 JAVA的内存结构 java队列 Java基础思考之数据传递 JAVA内存泄漏详解 java...

    Java开发详解.zip

    020507_【第5章:面向对象基础】_String类的常用方法.pdf 020508_【第5章:面向对象基础】_引用传递及其应用笔记.pdf 020509_【第5章:面向对象基础】_this关键字笔记.pdf 020510_【第5章:面向对象基础】_static...

    【大厂面试题总结】JavaSE面试题合集及其答案,基本包括javaSE所有知识点和详细解释

    深入理解Java的反射机制 深入理解Java异常体系 谈谈NIO的理解 谈一谈对JUC的理解 ArrayList的底层原理 HashMap的底层原理 iava单例模式详解 JAVA的内存结构 java队列 Java基础思考之数据传递 JAVA内存泄漏详解 java...

    深入理解Java String#intern()内存模型

    大家知道,Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,会在字符串常量池中创建该字符串然后再返回。  字符串常量池是一个固定大小的HashMap,桶的数量默认是1009, ...

    《剑指offer》Java-String、StringBuffer 和 StringBuilder 的区别.pdf

    String、StringBuffer 和 StringBuilder 的区别 ...深入理解 String、StringBuilder、StringBuffer 从设计角度理解 String StringBuilder StringBuffer StringBuilder 和 StringBuffer 的扩容问题 总结

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)命名习惯和注释 193 教学视频:43分钟 8.1 Java中的包(Package) 193 8.1.1 Java中的包 193 8.1.2 在Eclipse中使用包 194 ...

Global site tag (gtag.js) - Google Analytics