Java基础学习笔记:==、equals与包装类的核心考点
哈喽~今天又啃了一波Java基础知识点,主要聚焦在==和equals的区别、hashCode的关联,还有包装类的那些易踩坑点,整理成笔记方便以后回顾~
一、== 与 equals:别再傻傻分不清
首先要明确,== 和 equals 不是一回事,核心区别先拎清楚:
-
==的比较规则- 基本数据类型:比较的是值 是否相等(比如
int a=10, b=10; a==b → true); - 引用数据类型:比较的是内存地址是否相等(毕竟引用类型变量存的是对象的内存地址)。
- 基本数据类型:比较的是值 是否相等(比如
-
equals方法的本质equals是Object类的原生方法,所有类都默认继承,原生equals底层其实就是==(本质还是比较地址);- 但很多常用类会重写
equals,比如String类:先判断地址(==),地址不同再逐字符比较内容,所以String的equals是比较内容是否相等; - 自定义类(比如示例里的
Cat类):如果只重写equals不重写hashCode,会导致HashSet去重失效!因为HashSet是靠hashCode判断对象是否重复(hashCode默认是对象地址的哈希值),即便equals返回true,只要hashCode不同,HashSet仍认为是两个对象。
✨ 划重点:重写equals时必须重写hashCode,保证"相等的对象必须有相等的hashCode"(这是Java的约定)。
二、包装类:基本数据类型的"对象化"改造
Java里"万物皆对象",但8种基本数据类型(int、long、float、double、boolean、char、byte、short)并不是对象,包装类就是为了弥补这个短板而生~
-
基本数据类型 ↔ 包装类对应关系
| 基本数据类型 | 包装类 |
|--------------|--------------|
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| boolean | Boolean |
| char | Character |
| byte | Byte |
| short | Short |
-
自动拆装箱(编译期语法糖)
- 自动装箱:基本类型 → 包装类,编译时会被替换成
valueOf()方法
比如Integer c = 10;→ 编译后实际是Integer c = Integer.valueOf(10); - 自动拆箱:包装类 → 基本类型,编译时会被替换成
xxxValue()方法
比如int a = c;→ 编译后实际是int a = c.intValue();
- 经典坑:Integer的"128陷阱"
测试代码里发现一个有趣的现象:
java
Integer d = 128;
Integer e = 128;
System.out.println(d == e); // false
Integer f = 127;
Integer g = 127;
System.out.println(f == g); // true
原因藏在Integer.valueOf()的源码里:
JDK为了优化性能,给-128~127的Integer值做了缓存(一个叫cache的数组)。当自动装箱的值在这个区间时,直接返回缓存里的对象地址;超出区间则新建Integer对象,所以地址不同,==比较就为false。
✨ 提醒:比较Integer值建议用equals,而非==!
三、补全:基本数据类型与字符串的互转方法
日常开发中经常要把字符串转成基本类型,或把基本类型转成字符串,整理了全量转换方法,再也不用翻源码啦~
1. 字符串 → 各基本数据类型(核心:各包装类的parseXxx()/valueOf())
| 目标类型 | 转换方法(示例) | 备注 |
|---|---|---|
| int | String s = "123"; int num = Integer.parseInt(s); 或 Integer numObj = Integer.valueOf(s); |
超出int范围会抛NumberFormatException |
| long | String s = "123456"; long num = Long.parseLong(s); 或 Long numObj = Long.valueOf(s); |
- |
| float | String s = "12.3"; float num = Float.parseFloat(s); 或 Float numObj = Float.valueOf(s); |
支持科学计数法(如"1.23e2") |
| double | String s = "12.345"; double num = Double.parseDouble(s); 或 Double numObj = Double.valueOf(s); |
- |
| boolean | String s = "true"; boolean flag = Boolean.parseBoolean(s); 或 Boolean flagObj = Boolean.valueOf(s); |
非"true"(忽略大小写)都返回false |
| char | String s = "A"; char ch = s.charAt(0); |
字符串转单个字符(无parseChar方法) |
| byte | String s = "127"; byte num = Byte.parseByte(s); 或 Byte numObj = Byte.valueOf(s); |
byte范围:-128~127 |
| short | String s = "32767"; short num = Short.parseShort(s); 或 Short numObj = Short.valueOf(s); |
short范围:-32768~32767 |
2. 基本数据类型 → 字符串(3种通用方式)
方法1:拼接空字符串(最简单,可读性高)
java
int a = 123;
String s = a + "";
boolean flag = true;
String s2 = flag + "";
方法2:使用String.valueOf()(推荐,无异常风险)
java
int a = 123;
String s = String.valueOf(a);
long b = 123456;
String s2 = String.valueOf(b);
float f = 12.3f;
String s3 = String.valueOf(f);
方法3:各包装类的toString()方法
java
int a = 123;
String s = Integer.toString(a);
double d = 12.345;
String s4 = Double.toString(d);
byte bt = 10;
String s5 = Byte.toString(bt);
最后小结
今天的知识点看似基础,但都是面试和开发中的高频坑点:
- 别混淆
==和equals,重写equals必重写hashCode; - 包装类的自动拆装箱是编译期语法糖,
128陷阱要记牢; - 基本类型和字符串互转要熟练,注意
NumberFormatException异常;
基础不牢,地动山摇,慢慢啃慢慢记,Java路还长~