JAVA基础问题求解【创建对象的具体过程在内存中是怎么进行的?】
String a=new String("abcdef");
和
String a="abcdef";他们分别是在内存中怎么进行的呢?
还有个问题就是:
SomeClass a=new SomeClass();
a=new SomeClass();
new SomeClass();
他们三者之间有什么区别和联系呢?
谢谢! 展开
这个问题我回答你。
学过汇编语言的人都知道。
一个应用程序一般分为3个部分。
1.数据段
2.栈段
3.代码段
有关上面的具体含义,解释起来用的文字较多。你可以百度搜多一下。
或看看8086汇编
有关下面这个问题:
(1)
String a=new String("abcdef");
与
(2)
String a="abcdef";
他们是不一样的。
(2)是在编译器决定的,(1)是在运行期间决定的。
(2)中的abcdef存放在“栈”中。
而(1)中new出来的String存放在“堆”中
“栈”的大小是编译器确定下来的。(存取速相对"堆"较快)
而“堆”是动态创建的(Java中通过new创建的对象都是放在堆中的)
注意:我这里说的是创建出来的对象,而非存放对象引用的变量
(例如String a;)
SomeClass a=new SomeClass();
a=new SomeClass();
new SomeClass();
这3个的区别和联系。
区别就是在内存中创建了3个对象。
不同的就是,这3个对象有的存在引用关系(例如:a=new SomeClass(); )
有则则没有(new SomeClass(); )
没有存在引用关系的对象,将会在内存负载过大的时候,自动由Java的内存回收机制。将此块内存释放。
从汇编角度来讲:
什么是类呢?什么是对象?
看似一个很书面的问题。
其实不然!
我们可以把“类”看做一个飞机的设计图纸
而把对象是为按照这个图纸设计出来的一个实实在在看得见摸得着的“飞机”
对于这个例子:
SomeClass a = new SomeClass();
SomeClass b = new SomeClass();
他们有不同之处,也有相同之处。
从底层来讲。相同之处,是指他们用的都是同一块”代码段“
不同之处在于“数据”有所不同。
可能听起来有些不好理解。
其实你知道理解我最上面所讲的内容就足够了。
想学习更深入的内容,等以后有时间学习学习 80x86汇编。
看看《深入Java虚拟机》等相关书籍
我写的字有些多了。。。我也该看看新闻去了。。。再见哦~~
首先来了解java程序中内存的结构:
堆:存放所用new出来的对象
栈:存放对象的引用(也就是地址),基本数据类型产生的变量
常量池:(这个比较特殊)是用来存放String常量,如“abc”
你的例子:
String a = new String("abcdef");
因为有new,调用了String类的构造,在堆中产生了一个对象,值为“abcdef”,
然后在栈中声明一个引用a,把产生的对象的引用赋值给a;
String a = "abcdef";
这是声明一个字符串常量,首先在池中查找有没有这个“abcdef”,如果没有,在池中产生一个“abcdef”,然后把引用赋值给栈中的a
你的第二个问题
SomeClass a=new SomeClass();
这个就是在堆中构造一个对象,然后把引用传给栈中的a
a=new SomeClass();
这个语法是错误的,因为a没有声明
new SomeClass();
直接在堆中产生一个对象,但是没有传给栈中的一个引用(根据JAVA的垃圾回收机制,长时间不用,JVM会调用System.gc()方法析构掉这个对象)。
总结一下,你的第一种和第三种方法都可以产生一个对象,如果你只想产生一个对象然后只运行一次,可以用第3个,不过因为没有引用指向它,以后想使用这个对象而找不到;第一种是常见的方法,产生一个对象,并且声明栈中的一个引用指向它,以后可以用这个引用随时使用这个对象。
(其实有些不是绝对的,比如除了用new,反射机制也可以产生对象;而有时对象会放在栈中,这些你不用管)
说的有点啰嗦,大概就是这些。
和
String a="abcdef";
第一个是创建一两个对象,第二个是一个对象