Java对象的创建(1)

来源:互联网 发布:淘宝购物车排序 编辑:程序博客网 时间:2024/06/03 20:47

想必大家在面试或者学习的过程中,总会遇到类似的代码 String str=new String("abc"),这段代码创建了几个对象?解答这个问题,看似很容易, 但要正真回答到面试官期待的样子,实际上却很难,因为它涉及到string对象 的创建方式(构造方法),JVM,还有对象在内存中的存储位置等相关问题。我们一个一个来解答分析。

string str = 这部分,只是定义并赋值(某个对象在内存中的地址引用传递,也叫作句柄),所以这里无关紧要,没有发生创建对象这个关系(过程)。然后,有过Java基础的人都知道我们在使用new关键字创建对象时(不管是什么类型的对象),必然是经历一系列对象创建过程后,再产生对象的(指定对象类型,分配内存空间,某一个构造方法的执行,初始化赋值等等)。

但是,我们也会经常看到string a =“abc”这种赋值方式,其实这也是在创建对象了(我们可以称这种方式为引号赋值),要解释这种创建对象方式的袁莉,就必须要引入常量池(Constant pool的概念了,在这里多说一句,要想称为优秀的Java代码搬运工,我们除了要了解堆,栈的概念外,还应该了解寄存器,常量池,方法区等内存知识,我有空再写文章来介绍。在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。由于String类是final的,它的值一经创建就不可改变,因此不用担心String对象共享而带来程序的混乱。(红色这段话引用于360问答

再回头看看String a="abc";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。

只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,对此我们不再赘述。因此用引号包含文本的方式来创建String对象以提高效率,实际上这也是在编程中常采用的。(上面的两段话也是同一个地方的引用大笑

(从这里开始又是原创了)常量池的使用提高了很多效率,两种创建对象的区别是:new关键字创建的对象一定是新对象,而用引号创建的对象是共享的,写一个测试代码,如下:

String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。

String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。

现在你应该明白了要他们的区别了吧


回到最初的问题,那句代码String str=new String("abc"),创建了两个对象

原创粉丝点击