从JVM类加载的角度分析new String("")问题

回来写博客了,还好,没有失言。

 

先告诉一下读者,也许我也还没能够说的够明白,因为这个问题,真的,还是很复杂的;所以没那份完整的自信。

 

回归主题。

 

先来说一下JVM中内存的几个概念。(在上一篇博文中有同学让我加点图,这里特意找来一个class文件结构图,自己画图,总是不会用画笔,哎!)



 

 

方法区(Method Area),虚拟机栈(VM Stack),堆(Heap),本地方法栈(Native Method Stack),程序计数器。

 

那么在这里,就主要介绍一下:VM Stack与Heap。

VM Stack主要存放的是局部变量表部分,而局部变量表存放了编译期可知的各种基本类型数据(boolean,byte,char,short,int,float,long,double),对象引用(reference类型)和returnAddress类型(指向字节码指令的地址)。

Heap主要存放的就是对象实例。

 

先来用个简单的而复杂的例子说明一下:

Object obj = new Object();

 

看看这段代码

 

 

以上代码是通过javap命令反编译出的class代码,而代码就是:

public class obj {

    Object obj = new Object();

}

 

完整命令:javap -verbose obj。(当然要先通过javac obj.java先编辑一下,再反哦)

 

再来分析一下上面的代码:

{ 
java.lang.Object obj; 

public obj(); 
Code: 
Stack=3, Locals=1, Args_size=1 
0: aload_0   
1: invokespecial #1; //Method java/lang/Object."<init>":()V 
4: aload_0 
5: new #2; //class java/lang/Object 
8: dup 
9: invokespecial #1; //Method java/lang/Object."<init>":()V 
12: putfield #3; //Field obj:Ljava/lang/Object; 
15: return 
LineNumberTable: 
line 1: 0 
line 12: 4 
} 

 

 

首先:

 Stack=3, Locals=1, Args_size=1  其中Stack为栈编号,Locals为本地变量个数,Args_size参数个数。

aload_0:将指定的引用类型本地变量推送至栈顶

invokespecial:调用超类构造方法实例初始化

putfield:为指定的类的实例域赋值

dup:复制栈顶数值并将复制值压入栈顶

new:创建一个对象,并将其引用值压入栈顶

 

在这面的过程中,首先是在栈中本地变量表中创建一个reference类型数据,再在堆中创建一个Object的实例对象,而对象类型等信息保存到方法区。

 

再回到标题说的

String a = new String("abc");(当然这样写代码是错误的

可能大家都知道String做为了一个类实现,那么new一个实例时,就在堆中创建一个实例对象,而“abc”也是保存在这块内存中,与String b = "abc";中的值"abc"存放的地址是不一样的。而a==b比较的是两个地址的值。当然在new String("abc")的时候,abc会放入到共享池中,不过与a引用的地址已经不是一样了。

比如:

package test;

public class String1 {
	st a = new st(1);
	st b = new st(1);

	public static void main(String args[]) {
		String1 cfb = new String1();
		
		if(cfb.a  == cfb.b){
			System.out.println("地址相等,你会相信吗?");
		} else{
			System.out.println("地址不相等.");
		}

	}
	class st {
		int b;
		public st(int b){
			this.b = b;
		}
	}
}

 

最后肯定是输出不相等了。

 

 

 

最后,总结一下上面所说的,还是有些混,没有写的很清楚的感觉,也许这就是我对JVM的理解还不深的原因是,应该把类加载的过程说的更清楚。

 

最后给一个我看的博文地址:

从“关于Java堆与栈的思考”一帖看错误信息的传播 作者:ZangXT

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值