Java常量池、==、equals用法剖析

数据存储类型
存储器类型 存储区域
内存 RAM、ROM
外存 硬盘

RAM:random access memory,随机存储器;可读可写;不存储;运行内存
ROM:read only memory,只读存储器;只可读;存储

数据存储区域
存储区名称 存储数据类型 存储区域 功能特性
寄存器 处理器内部 最快存储区
对象引用、基本数据类型值 通用RAM 堆栈指针向下移动,分配新内存;指针向上移动,释放旧内存;数学计算在内存栈进行
所有Java对象、new创建新对象、构造器创建对象 通用内存池(位于RAM区) 自动分配内存,无序
常量存储(常量池、静态区) 程序中的字面量(Java变量、常量值) 程序代码内部、ROM区 不可变
非RAM存储 流对象、持久化对象等 磁盘、硬盘、数据库等 独立存在

常量池中包含:
1.代码中所定义的各种基本数据类型
2.对象型(String和数组)的常量值
3.以文本形式出现的符号引用:方法、字段、类和接口的名称和描述符

名称 常量池
实现类 Byte、Short、Integer、Long、Character、Boolean、String
未实现类 FloatDouble
存储范围 -128~127(超出部分存入Heap堆)

实战1:==与equals

数据类型 == equals
基本数据类型 比较数值 --
包装类、String类 比较地址 比较内容(重写equals方法)

注意:Integer类、String类对equals方法重写,但父类Object类未重写equals方法,故其他子类equals方法比较的也是“引用”地址。

类型1:a与b(Integer类、Double类)
类型 a b == equals 解析
1 int a=89; Integer b=89; true -- --
2 int a=129 Integer b=129; true -- --
3 int a=89; Integer b=new Integer(89); true -- --
4 int a=129; Integer b=new Integer(129); true -- --
5 Integer a=89; Integer b=89; true true -128~127
6 Integer a=129; Integer b=129; false true -128~127
7 Integer a=89; Integer b=new Integer(89); false true new
8 Integer a=129; Integer b=new Integer(129); false true new
9 double a=129.1 double b=129.1; true -- --
10 Double a=129.1 Double b=129.1; false true Double不支持常量池
类型2:a+b与c(Integer类)
类型 a b c a+b==c equals
1 Integer a=129; Integer b=0; Integer c=129; true true
2 Integer a=new Integer(129); Integer b=0; Integer c=new Integer(129); true true

解析:Integer对象无法与数值进行直接比较,所以Integer对象首先进行拆箱后进行数值计算。(参考资料:技术小黑屋-Java中的自动装箱与拆箱)

类型3:a+b与c(String类)
类型 操作 ==
1 String a="hello";String b="world";String c="helloworld"; a+b==c false
2 String a="hello";String b="world";String c="helloworld"; a+"world"==c false
3 String a="hello"+"world";String c="helloworld"; a==c true
4 final String a="hello";final String b="world";String c="helloworld"; a+b==c true
5 final String a="hello";final String b="world";String c="helloworld"; a+"world"==c true

解析:String类的intern()方法检测常量池中是否存在字符串,若存在返回引用,若不存在,则创建并返回引用。(同类参考:梦工厂-Java常量池理解与总结)

实战2:重写equals()方法和hashCode()方法
public class Main {
    private int num;
    private String name;
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;`
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Main main = (Main) obj;
        if (name == null) {
            if (main.name != null) {
                return false;
            }
        } else if (!name.equals(main.name)) {
            return false;
        }
        return true;
    }
    @Override
    public int hashCode(){
        final int prime=31;
        int hash=1;
        hash=prime*hash+num;
        hash=prime*hash+((name==null)?0:name.hashCode());
        return hash;
    }
}

你可能感兴趣的:(Java常量池、==、equals用法剖析)