Java的引用和内存

2023年6月25日09:07:25

例子

public class Square {  
    long width;  
    public Square(long l) {   
        width = l;  
    }  
    public static void main(String arg[]) {
    	//声明了3个Square类型的变量a,b,c
    	//在stack中分配3个内存,名字为a,b,c
        Square a, b, c;
        //在heap中分配了一块新内存,里边包含自己的成员变量width值为42L,然后stack中的a指向这块内存
        a = new Square(42L);
        //在heap中分配了一块新内存,里边包含自己的成员变量width值为42L,然后stack中的b指向这块内存
        b = new Square(42L);
        //stack中的c也指向b所指向的内存 
        c = b;
        //在stack中分配了一块内存,值为42   
        long s = 42L;  
    } 
}

以上代码在内存中的情况:
Java的引用和内存

如何来对各种不同的变量作比较?

java的数据类型分为:

  1. 基本数据类型
  2. 引用数据类型
    Java的引用和内存
    上例中的变量a,b,c属于引用数据类型,s属于基本数据类型

==强调栈中的比较,可以理解为地址比较
==可以用于基本数据类型相互比较,此时比较二者的是否相等
==也可以用于引用数据类型的相互比较,此时比较二者的地址是否相等
==不能用于基本数据类型和引用数据类型比较,不同的基本数据类型之间也不能比较,例如string不能与char[]比较

equals强调对象的内容比较
equals不能用于基本数据类型比较,因为这是一个方法,不是运算符,继承自object
equals用于进行对象的比较,比较二者的引用地址是否相同

特殊情况:
1)数值型基本类型和数值型类会存在自动装箱和自动拆箱.
2)字符串会以常量形式存在, 如果多个字符串变量值相同, 则他们指向同一个地址.
3)数值类型会存在类型自动转换.

根据给出的例子判断

  • 由图可以看出a和b指向的不是同一个引用,所以a!=b

  • 一个Square类型不能与一个long型比较,编译就错误,所以不存在s==a这种比较

  • 由图可以看出b和c指向的是同一个引用,所以b==c

  • 程序会把s封装成一个Long类型,由于Square没有重写Object的equals方法,
    所以调用的是Object类的equals方法,源码如下
    public boolean equals(Object obj) {
    return (this == obj);
    }
    其实就是判断两个引用是否相等,所以a.equals(s) == false

    在java中进行比较,我们需要根据比较的类型来选择合适的比较方式:

  1. 对象域,使用equals方法 。
  2. 类型安全的枚举,使用equals或== 。
  3. 可能为null的对象域 : 使用 == 和 equals 。
  4. 数组域 : 使用 Arrays.equals 。
  5. 除float和double外的原始数据类型 : 使用 == 。
  6. float类型: 使用Float.foatToIntBits转换成int类型,然后使用==。
  7. double类型: 使用Double.doubleToLongBit转换成long类型,然后使用==。
  • 作者:细嗅潇洒的蔷薇
  • 原文链接:https://blog.csdn.net/sinat_34212400/article/details/103339758
    更新时间:2023年6月25日09:07:25 ,共 1237 字。