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

JVM对String对象的处理

阅读更多
java 代码
  1.   
  2. /**  
  3.  *   
  4.  * java JVM 对String对象的处理  
  5.  * test String. intern() 方法   
  6.  *   
  7.  */  
  8. public class TestStringIntern {   
  9.   
  10.   
  11.     /**  
  12.      * @param args  
  13.      */  
  14.     public static void main(String[] args) {   
  15.            
  16.         /*  
  17.          * 1.字面上的 "Hi" 字符串(字符串字面值string literal)将被自动 intern到虚拟机的字符串池中.  
  18.          * 2.不是字面上的String对象 通过调用 intern()方法,被intern到虚拟机的字符串池中.  
  19.          *   
  20.          * 虚拟机的字符串池由类 String 私有地维护。  
  21.          */  
  22.         String a = "Hi";   
  23.         String b = "Hi";   
  24.         String c = new String("Hi");   
  25.   
  26.         System.out.println(a == b);// true   
  27.         System.out.println(a == c);// false   
  28.            
  29.         c = c.intern();   
  30.         System.out.println(a == c);// true   
  31.            
  32.         /*  
  33.          * 创建了两个对象   
  34.          * 1.字面"AA" ——被intern到虚拟机字符串池中了。  
  35.          * 2.new 操作符创建的 对象  
  36.          *   
  37.          * 由AA != AA.intern()可以看出:String AA = new String("AA");创建了两个对象。  
  38.          */  
  39.         String AA = new String("AA");   
  40.         System.out.println(AA == "AA");// false   
  41.         System.out.println(AA == AA.intern());// false   
  42.         System.out.println("AA" == AA.intern());// true   
  43.            
  44.            
  45.         /*  
  46.          * JAVA 规范中的例子:  
  47.          */  
  48.         String hello = "Hello", lo = "lo";   
  49.         System.out.print((hello == "Hello") + " ");      //true   
  50.         System.out.print((hello == ("Hel"+"lo")) + " "); //true   
  51.         System.out.print((hello == ("Hel"+lo)) + " ");   //false--lo为非literal的   
  52.         System.out.println(hello == ("Hel"+lo).intern());//true   
  53.   
  54.     }   
  55.   
  56. }   
  57.   
分享到:
评论
14 楼 hbcui1984 2007-04-16  
skydream 写道
对这个的解释,我有不同的想法
"Hel"+"lo"这个表达式,编译器是有优化的,因为string是不可变的,因此"Hel","lo"都是常量,"Hel"+"lo"是常量表达式。java语言规范中常量表达式是在编译时进行求值的。因此对于"Hel"+"lo"被编译器直接处理为"Hello"。

总之,先是编译器先进行特殊处理,然后才是jvm处理,依据楼主说明的处理方式,最后得出一个true.

正解
13 楼 shaobin0604 2007-04-15  
skydream 写道
对这个的解释,我有不同的想法
#         System.out.print((hello == "Hello") + " ");      //true  
#         System.out.print((hello == ("Hel"+"lo")) + " "); //true 
hello == ("Hel"+"lo")的结果为true,没有疑义。但是为什么是true,我认为这里应该增加一个注释,才能准确的说明问题,即"Hel"+"lo"这个表达式,编译器是有优化的,因为string是不可变的,因此"Hel","lo"都是常量,"Hel"+"lo"是常量表达式。java语言规范中常量表达式是在编译时进行求值的。因此对于"Hel"+"lo"被编译器直接处理为"Hello"。

总之,先是编译器先进行特殊处理,然后才是jvm处理,依据楼主说明的处理方式,最后得出一个true.
楼上的正解
12 楼 skydream 2007-01-18  
对这个的解释,我有不同的想法
#         System.out.print((hello == "Hello") + " ");      //true  
#         System.out.print((hello == ("Hel"+"lo")) + " "); //true 
hello == ("Hel"+"lo")的结果为true,没有疑义。但是为什么是true,我认为这里应该增加一个注释,才能准确的说明问题,即"Hel"+"lo"这个表达式,编译器是有优化的,因为string是不可变的,因此"Hel","lo"都是常量,"Hel"+"lo"是常量表达式。java语言规范中常量表达式是在编译时进行求值的。因此对于"Hel"+"lo"被编译器直接处理为"Hello"。

总之,先是编译器先进行特殊处理,然后才是jvm处理,依据楼主说明的处理方式,最后得出一个true.
11 楼 zhsx2221 2006-12-29  
aone 写道
System.out.print((hello == ("Hel"+lo)) + " ");   //false--lo为非literal的
不是太明白这一句,能不能解释一下?


首先解释一下 “那张表”不是HASHTABLE,而是JVM内部维护的常量池;
对于 System.out.print((hello == ("Hel"+lo)) + " ");   这一句 要和
     System.out.print((hello == ("Hel"+"lo")) + " "); 来对照解释 :

在以上两句中("Hel"+lo) 创建了新的对象 而 ("Hel"+"lo")没有创建新的对象,而是从JVM字符串常量池中获取之前已经拘留了的"Hello"对象。

actually ,a string-valued constant expression,formed from two string literals。
同样它首先会从JVM字符串常量池中查找相应的 String对象(如“Hello”),如果找到则直接获取引用,如果不存在那么它也会被JVM拘留/intern 。

对于("Hel"+lo)创建了新的对像是因为:lo 是一个变量/引用,它并不是字面上的字符串(string literal),同理这个 表达式 也并不是一个string-valued constant expression,所以他不会被拘留,而是创建 一个新的对象。

---------
越说越绕,希望能理解......


10 楼 wjtang 2006-12-22  
get
9 楼 aone 2006-12-22  
System.out.print((hello == ("Hel"+lo)) + " ");   //false--lo为非literal的
不是太明白这一句,能不能解释一下?
8 楼 dwangel 2006-12-22  
galaxystar 写道
ahuaxuan 写道
事实上,每一个jvm必须维护一张内部表,它会列出所有在程序运行的过程中被拘留的字符串对象引用。基本上,如果一个字符串在jvm的这张内部表上出现,就是说它是被jvm所拘留的。维护这个列表的关键是任何特定的字符序列在这个列表上只出现一次。比如说上面的"hello",被拘留之后,虚拟机会使用指向以前拘留的字符串对象的引用,也就是说引用a和引用b是一个引用,这也解释了为什么a==b是为true的


a == b,记得是用hashCode比较的!你说的那张内部表,是指HashTable吗?

是比较a跟b这个变量里的内存地址不是hashCode。
7 楼 liucjj 2006-12-21  
c应该是引用的内存地址,那么a呢
6 楼 ahuaxuan 2006-12-20  
引用
galaxystar说道:

a == b,记得是用hashCode比较的!你说的那张内部表,是指HashTable吗?



我想这个内部表是jvm内部的表示,而jvm是c写的,是不是HashTable我就不知道了,c我不熟,hashcode 本身也是一个jni调用,如果对jvm不是非常熟的话,很难知道jvm是怎么做的
5 楼 galaxystar 2006-12-20  
ahuaxuan 写道
事实上,每一个jvm必须维护一张内部表,它会列出所有在程序运行的过程中被拘留的字符串对象引用。基本上,如果一个字符串在jvm的这张内部表上出现,就是说它是被jvm所拘留的。维护这个列表的关键是任何特定的字符序列在这个列表上只出现一次。比如说上面的"hello",被拘留之后,虚拟机会使用指向以前拘留的字符串对象的引用,也就是说引用a和引用b是一个引用,这也解释了为什么a==b是为true的


a == b,记得是用hashCode比较的!你说的那张内部表,是指HashTable吗?
4 楼 zhsx2221 2006-12-20  
用例子说话,再加上相关的注释 会比白话描述更清晰 hehe
3 楼 gao277 2006-12-15  
以前觉得自己挺明白这个东西的,看了文章以后更加明白了。
2 楼 ahuaxuan 2006-12-15  
事实上,每一个jvm必须维护一张内部表,它会列出所有在程序运行的过程中被拘留的字符串对象引用。基本上,如果一个字符串在jvm的这张内部表上出现,就是说它是被jvm所拘留的。维护这个列表的关键是任何特定的字符序列在这个列表上只出现一次。比如说上面的"hello",被拘留之后,虚拟机会使用指向以前拘留的字符串对象的引用,也就是说引用a和引用b是一个引用,这也解释了为什么a==b是为true的
1 楼 icefire 2006-12-08  
String a = "Hi";   
String b = "Hi";

系统对所有的字符串常量和常值的String表达式都自动进行扣留。
因为String类型对象被称作是永久的.

相关推荐

    Java对象创建方式及JVM对字符串处理

     在讲Jvm对字符串的处理之前,我们先来讲一下,在Java中,常见的5种创建对象的方式:  1)通过关键字new调用构造器创建Java对象,eg:String str = new String("hello");  2)通过Class对象的newInstance()...

    Java进阶教程解密JVM视频教程

    * 在垃圾回收章节,不仅会介绍垃圾回收算法、分代垃圾回收机制,还会重点介绍 G1 垃圾回收器,辨析 Full GC 发生条件,jdk8以来对垃圾回收的优化,以及垃圾回收的调优法则。 * 在字节码与类加载技术章节,会从一个 ...

    Java面向对象程序设计笔记

    2.对String对象操作的类 24 3. 对时间处理的类 25 4. 对系统处理的类: 26 5. 数据运算的类 27 6. 正则表达式 27 第七章 异常处理 32 第八章Oracle数据库基础 32 第九章JDBC编 32 第十章GUI编程 ...

    Ruby语言中的String深入理解

    比如 代码如下: str1=”abc” str2=”abc” 在java中,对于字面量的字符串,jvm内部维持一张表,因此如果在java中,str1和str2是同一个String对象。而在Ruby中, str1和str2是完全不同的对象。同样,在java中对于...

    【05-面向对象(下)】

    •但对引用类型的变量而言,它仅仅保存的是一个引用,final只能保证他的地址不变,但不能保证对象,所以引用 类型完全可以改变他的对象。 可执行“宏替换”的final变量 •对一个final变量来说,不管它...

    超级有影响力霸气的Java面试题大全文档

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

    面试必问Java面试题,对标初级Java

    5.说一下你对分布式理解是什么样的? 6.多线程 7. java集合 8.数据库事务 9.Mybatis 10.JVM、JRE、JDK的关系 11.servlet声明周期 12. java常用设计模式 13.Spring的核心 14.怎样声明一个类不会被继承,什么场景下会...

    涵盖了90%以上的面试题

    new String(“abc”)创建了几个对象 String变量做“+”运算时的编译优化 "=="和equals方法究竟有什么区别 String,StringBuffer,StringBuilder有什么区别 java中的数组是不是对象 数组初始化的方式有哪几种 length...

    Java基础知识点 - 内容比较全面

    1.5 JVM ClassLoader机制 1.6 Java中的synchronized使用 1.7 Java中的反射机制 1.8 Java中Heap与Stack的区别 1.9 Java中String和StringBuffer的区别 1.10 Java中Comparable和Comparator实现对象比较 1.11 Java...

    java 面试题 总结

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

    java面试宝典2012版.pdf

    这两行代码执行后,原始的String对象中的内容到底变了没有? 32、是否可以继承String类? 33、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别? 34、String 和StringBuffer的区别 35、...

    java面试题

    答:创建了两个String对象,一个保存的引用地址,一个保存实际的值。 数组有没有length()这个方法?String呢? 答:数组里面没有length()方法,而是length属性。String有length()这个方法。 swtich()能否作用在byte...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【多线程】线程池对任务的处理 85 【多线程】线程池的状态 86 线程池的状态说明 86 各个状态之间的转换 86 【多线程】什么是线程池?如果让你设计一个动态大小的线程池,如何设计,应该有哪些方法? 87 【多线程】...

    千方百计笔试题大全

    18、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 9 19、是否可以继承String 类? 9 20、以下二条语句返回值为true 的有: 10 21、当一个对象被当作参数传递到一个方法后,此方法可...

    java面试宝典

    18、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 9 19、是否可以继承String 类? 9 20、以下二条语句返回值为true 的有: 10 21、当一个对象被当作参数传递到一个方法后,此方法可...

    net学习笔记及其他代码应用

    答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 40.接口是否可...

    JSTL详细标签库介绍

    <!...<HTML><HEAD>关于java异常处理(讲义)--JSP中文网 ...第二步:处理对象与方法:声明4个GUI组件对象和1个用于存储计算结果(double)的和2个被除数与除数基本类型(int)<BR><BR>A、 初始化对象方法init()<BR>B...

    JAVA面试题最全集

    一、Java基础知识 1.Java有那些基本数据类型,String是不是基本...这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() ...

    Java基础知识点总结.docx

    < java.lang >String字符串:★★★☆ 71 < java.lang >StringBuffer字符串缓冲区:★★★☆ 73 < java.lang >StringBuilder字符串缓冲区:★★★☆ 74 基本数据类型对象包装类★★★☆ 75 集合框架:★★★★★,...

Global site tag (gtag.js) - Google Analytics