01.Java基础
# 01.数据类型
# 1、基本类型
- Java 提供 8 种基本数据类型,它们直接存储在栈(Stack)中,效率较高,不涉及对象的引用
类型 | 默认值 | 大小 | 范围 |
---|---|---|---|
byte | 0 | 8位 | -128到127 |
short | 0 | 16位 | -32768到32767 |
int | 0 | 32位 | -2147483648到2147483647 |
long | 0L | 64位 | -9223372036854775808到9223372036854775807 |
float | 0.0f | 32位 | 约±1.4e-45到±3.4e38, 精度为7位有效数字 |
double | 0.0d | 64位 | 约±4.9e-324到±1.8e308, 精度为16位有效数字 |
char | '\u0000' | 16位 | 0到65535 |
boolean | false | - | true或false |
# 2、包装类型
Java 中的
包装类型
是为了将上面8种基本数据类型
封装成对象而设计的Java 集合框架(如
ArrayList
,HashMap
等)只能存储对象,不能存储基本数据类型(需要使用包装类型来存储基本数据类型)包装类型提供了许多实用的方法,如类型转换、比较、字符串解析等
基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成
Integer x = 2; // 装箱 调用了 Integer.valueOf(2)
int y = x; // 拆箱 调用了 X.intValue()
1
2
2
# 3、缓存池
缓存池(Cache Pool)是一种优化机制,主要用于缓存一些常用的对象,以减少对象的创建和销毁开销
缓存池通常用于包装类型(如
Integer
、Long
等)和一些不可变对象(如String
)下面以
String
缓存池举例说明字符串常量池 是 JVM 专门存储字符串常量 的一个内存区域
相同的字符串只存储 一个副本,避免创建多个相同的字符串对象
// 示例 1:字符串常量池复用
String s1 = "hello"; // 存入常量池
String s2 = "hello"; // 直接引用常量池中的 "hello"
// 示例 2:使用 new String()
// 会在 堆( 中创建新的 String 对象,不会复用常量池 中的 "hello"
String s1 = new String("hello"); // 创建新的对象
String s2 = "hello"; // 引用常量池
System.out.println(s1 == s2); // false,不同对象
// 示例 3:使用 intern()
// 如果我们希望 new String("hello") 也指向常量池中的 "hello",可以使用 intern() 方法
String s1 = new String("hello").intern(); // 将 "hello" 放入常量池
String s2 = "hello";
System.out.println(s1 == s2); // true,两个都指向常量池
// 示例 4:字符串拼接 直接存入 常量池
// 示例 5:StringBuilder 不使用常量池
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4、String、StringBuffer、StringBuilder
1)
String
(不可变,适用于少量修改)在循环内使用“+”进行字符串的拼接的话,存在比较明显的缺陷
编译器不会创建单个
StringBuilder
以复用,会导致创建过多的StringBuilder
对象String s1 = "Hello"; String s2 = s1 + " World"; // 创建了新的字符串对象
1
2
2)
StringBuffer
(可变 线程安全,适用于多线程)3)
StringBuilder
(可变,适用于单线程,高性能)
# 02.Object 通用方法
# 1、== 和 equals() 的区别
==
比较的是内存地址
或基本数据类型的值
String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); // false,不是同一个对象
1
2
3
equals()
,使其比较字符串的内容
String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1.equals(s2)); // true,因为 "hello".equals("hello")
1
2
3
# 2、hashCode()
hashCode()
方法的作用是返回对象的哈希码(整数值eg: 12345678
)hashCode()
用于哈希存储(如HashMap
、HashSet
),判断元素是否在对应容器中的效率会更高- 同样的
hashCode
有多个对象,它会继续使用equals()
来判断是否真的相同 - 也就是说
hashCode
帮助我们大大缩小了查找成本hashCode
值相等,不一定相等(哈希碰撞),hashCode
值不相等,两个对象一定不相等- 注:
hashCode
值相等并且equals()
方法也返回true
,我们才认为这两个对象相等。
// 即使 p1 和 p2 的内容相同, 仍然具有不同的哈希码, hashCode() 方法基于对象地址计算
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
System.out.println(p1.hashCode()); // 12345678
System.out.println(p2.hashCode()); // 87654321
1
2
3
4
5
6
2
3
4
5
6
# 3、深拷贝和浅拷贝
浅拷贝(Shallow Copy):
仅复制对象的基本数据类型字段和对象引用(即复制的是引用地址,而不是实际的对象)。
复制后的对象与原对象
共享同一块内存的引用字段
,修改其中一个的引用对象,另一个也会受到影响。
深拷贝(Deep Copy):
复制对象的基本数据类型字段,并且对引用类型字段
创建新的对象
,使它们不共享相同的内存地址
。修改新对象的引用字段不会影响原对象。
// clone() 方法默认是浅拷贝,如果类有复杂对象字段,需要手动实现深拷贝
Person p1 = new Person();
Person p2 = (Person) p1.clone(); // 复制对象
1
2
3
2
3
# 03.反射
什么是反射?
- 反射(Reflection)是 Java 提供的一种机制,允许在运行时动态获取类的信息(字段、方法、构造函数等)
- 并能动态调用方法或创建对象,而不需要在编译时确定类的具体信息
反射用法
- 反射强大但有性能损耗,建议在框架开发、动态代理等需要灵活性的场景中使用
反射用途 | 代码示例 |
---|---|
获取类信息 | Class<?> clazz = Class.forName("Person") |
获取字段信息 | Field field = clazz.getDeclaredField("name") |
动态创建对象 | clazz.getDeclaredConstructor().newInstance() |
调用方法 | method.invoke(obj) |
上次更新: 2025/2/19 16:42:39