先理解JVM内存模型
- 虚拟机栈:JVM 运行过程中存储当前线程运行方法所需的数据, 指令、 返回地址
- 本地方法栈:Java程序自动调用底层C/C++函数库
- 程序计数器:当前线程执行的字节码的行号指示器
- 堆:存放我们申请的对象,也就是实例化对象,数组等
- 方法区:存放虚拟机加载的类相关信息,包括类信息,静态域(静态变量和静态方法),常量池(const val修饰的变量)、字符串常量池、编译后代码等
变量内存位置
- 所有线程共享的方法区中有一个常量池,存储 整型和浮点型,字符型和字符串、布尔值
- 引用类型(包括String,需要手动申请存储空间的)都在堆中存储
==的使用
1.使用范围
所有基本类型和引用类型通用
2.判断原理
- 比较两个基本类型,判断值是否相等
- 比较两个引用类型,判断内存地址是否相等
3.实例演示
String str1 = "a"+"b"+"c";
String str2 = "abc";
String str3 = new String("abc")
str1 == str2; // 结果为true
str1 == str3; // 结果为false
str2 == str3; // 结果为false
- String字符串为引用类型
- str1实际就是"abc",首次出现,在字符串常量池创建内存
- str2属于字符串,"abc"在str1中已在常量池创建,所以直接获取常量池"abc"内存地址
- str3属于手动申请变量空间,在堆中存储
- String属于引用类型,== 旨在判断二者内存地址,因此str1与str2同在常量池,str3在堆中
equals()使用
1.使用范围
只用于引用类型和基本类型的包装类,八大基本类型不可使用
2.判断原理
- equal 不重写 即判断内存地址是否相同
- equal 重写后 可以判断值是否相同(String的equal是系统自己重写了,判断值是否相同)
//JAVA中重写String 源码
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
3.实例演示
Integer i1=new Integer(4);
Integer i2=new Integer(5);
Integer i3=new Integer(i1+i2);
Integer i4=new Integer(9);
i1.equals(i2); //结果为false
i1.equals(i4); //结果为false
i3.equals(i4); //结果为true
- 基本类型int的包装类Integer,属于引用类型,可以使用equals()
- 手动申请空间创建对象,都在堆中分配内存,i1,i2,i3,i4都独立存储
- Integer的equals方法被系统重写,判断两者保存值是否相同
- i1,i2,i4,i3存储空间相互独立,但是由于i3和i4存储值皆是9,所以结果为true