`

其实你不清楚String、Integer等类在内存中如何组织数据!

 
阅读更多
我们往往一直半解,我们知道stack中有String池,可是不知道为什么有了线程池就能使String类的对象表现出基本数据类型的特征(多重引用其中一个引用改变了值另外几个引用的值并没有改变),我们也不知道到底new一个String和用"='a'"创建一个String对象到底有什么区别?我们不清楚包装类到底是怎么回事,他们和String类型有什么相似和不同之处?
如果,上面的问题您都能很清晰,那么没有必要浪费你宝贵的时间继续看了。否则,请允许我把我一点理解分享给大家,跟着我继续往下走!

这是我自己画的图:





跟着我来读这个图:

String的new和"='a'"的区别:

    如果String str=new String("aaa");JVM在heap中开辟String内存空间后,在stack中寻找是否已经有"aaa"存在。若不存在,分两步走:
     1、就在stack中创建一个"aaa"数组array,然后再heap中创建一个String o;(单独的,不同于str),让o中的char[]指向array首地址,再将array绑定o对象地址 
     2、将str中的char[]地址指向o中的char[]指向的对象,即将str中的char[]直接指向array首地址
如果"aaa"已经存在,很好办,通过array找到o,然后执行第二步就好。
这样就造成一种假象,没new一String都会重新非配char[]内存,实际不是如此。之所以有这种错觉,是因为每new一个String 索引str所指向的地址不同而已。

     如果是String str="aaa";如果stack中没有"aaa"的数组,那么将和上面步骤1中进行同样的操作,只不过2步骤不同:不是单独在heap中开辟一块String的空间了,而是所有的对象的索引str都直接指向第1步中创建的o。

String和普通包装类的区别:

普通包装类只有部分值存在类似String中o对象(如Integer是-128~127),另外的值不管是new还是用=都是重新在heap中开辟空间,尽管最终heap中的的索引也是指向stack中的同一内存区域(栈中不会有int的两个相同值,不过可以有两个相同值的索引)。



上代码:
public class HeapDemo {
	public static void main(String args[]){
		Integer i=new Integer(2);
		Integer j=new Integer(2);
		System.out.println(j.intValue()==j.intValue());//true
		System.out.println(i==j);//false
		
		Integer h=10;
		Integer k=10;
		System.out.println(h==k);//true
		
		Integer u=new Integer(1001);//超过缓存范围
		Integer uu=new Integer(1001);
		System.out.println(u.intValue()==uu.intValue());//true
		System.out.println(uu==u);//false
		
		Integer q=1000;//超过缓存范围
		Integer qq=1000;
		System.out.println(q==qq);//false
		
		
		
		String r=new String("bbb");
		String rr=new String("bbb");
		System.out.println(r.charAt(0)==rr.charAt(0));//true
		System.out.println(r==rr);//false
		
		
		String s="aaa";
		String ss="aaa";
		System.out.println(s==ss);//true
		
	}
}




  • 大小: 90.5 KB
分享到:
评论
3 楼 贾懂凯 2010-12-29  
freish 写道
会被投新手贴么?

我是小白菜,重在交流和分享
2 楼 血腥小苹果 2010-12-29  
freish 写道
会被投新手贴么?

早些时候遇到了这个问题。也解决了。虽然是个基础问题。现在又温习遍。
1 楼 freish 2010-12-29  
会被投新手贴么?

相关推荐

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

     声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,...

    java经典面试题.doc

    不是,Java中最基本的数据类型包括`int`、`float`、`boolean`等,`String`是引用类型。 #### 56. int和Integer有什么区别? - `int`是基本数据类型。 - `Integer`是`int`的包装类。 #### 57. 运行时异常与一般...

    《你必须知道的495个C语言问题》

    《你必须知道的495个C语言问题》以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预...

    java程序员获Offer必备宝典.pdf

    - **深入理解`==`和`equals()`的使用场景**:在面试中能够清楚解释不同数据类型下它们的行为差异,并举出实际例子来说明。 - **掌握哈希表和对象等价性的概念**:能够阐释`hashCode()`和`equals()`在对象比较中的...

    DWR.xml配置文件说明书(含源码)

    这有点向java中的import语句,多数类在使用之前需要引入,但引入了类并不意味着这些在使用,每个creator和converter需要有个id属性来允许以后进行引用. 配置文件的allow部分定义哪些类可以建立和转换,每个被准许的类都...

    java equals和=,==的区别详细介绍

    但在某些类(如 `String`、`Integer`、`Date` 等)中,`equals()` 方法被重写以比较对象的内容或状态,而非内存地址。 - 对于未重写 `equals()` 的自定义类,`equals()` 方法的行为与 `==` 相同,即比较对象的引用...

    VB程序设计填空.docx

    - **知识点**: VB中的`Integer`类型用于存储整数值,它占用固定的内存空间。 - **解析**: `Integer`类型变量占用2个字节的空间。这是因为Visual Basic为了兼容性和性能考虑,固定了`Integer`类型的内存占用。 #### ...

    Android编程之SQLite数据库操作方法详解

    在Android中使用SQLite数据库并不需要安装过程和获取数据库使用权限,你只需要定义创建和更新数据库的语句即可,其他的会由Android平台替你搞定。操作SQLite数据库通常意味着操作文件系统,这种操作还是比较耗时的,...

    Google C++ Style Guide中文版

    嵌套类可以在逻辑上将一组相关的类组织在一起,但也可能导致代码难以阅读和维护。只有当嵌套类与外层类有很强的联系时,才考虑使用嵌套类。 - **外部函数、静态成员函数和全局函数 (Nonmember, Static Member, and...

Global site tag (gtag.js) - Google Analytics