文章目录
-
- 什么是反射
- 反射的常用场景
- [Java 注解的原理](#Java 注解的原理)
- 异常机制详解
-
- 异常处理方式
-
- [1. try-catch-finally](#1. try-catch-finally)
- [2. 抛出机制](#2. 抛出机制)
- [equals 与 == 的区别](#equals 与 == 的区别)
- [hashCode 与 equals 的关系](#hashCode 与 equals 的关系)
-
- [String vs StringBuffer vs StringBuilder](#String vs StringBuffer vs StringBuilder)
- [Java 8 核心新特性](#Java 8 核心新特性)
-
- [1. Lambda 表达式](#1. Lambda 表达式)
- [2. 函数式接口](#2. 函数式接口)
- [3. Stream API](#3. Stream API)
- [4. Optional 类](#4. Optional 类)
- [5. 其他重要特性](#5. 其他重要特性)
什么是反射
反射是指程序在运行过程中,对于任意一个类,都能获取它的属性和方法;对于任意一个对象,都能调用其属性和方法。这种动态获取类信息并操作对象的能力称为 Java 的反射机制。
// 反射示例:获取类方法
Class<?> clazz = Class.forName("java.lang.String");
Method method = clazz.getMethod("length");
int length = (int) method.invoke("Hello"); // 返回 5
反射的常用场景
| 场景 |
说明 |
| 配置文件 |
动态加载配置中指定的类(如 Spring 的 applicationContext.xml) |
| 注解 |
反射是读取注解含义的核心工具(如 @Override、@Autowired) |
| 框架 |
Spring、Hibernate 等框架通过反射实现依赖注入和动态代理 |
Java 注解的原理
注解本质是一个继承了 Annotation 的接口,其具体实现类是 JVM 运行时生成的动态代理类。通过反射获取注解时,返回的是动态代理对象。
// 注解定义示例
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
// 反射获取注解
MyAnnotation anno = MyClass.class.getAnnotation(MyAnnotation.class);
System.out.println(anno.value()); // 输出注解值
异常机制详解
异常类层次结构
Throwable Error Exception OutOfMemoryError RuntimeException IOException NullPointerException IndexOutOfBoundsException FileNotFoundException
异常分类
| 类型 |
特点 |
示例 |
| Error |
JVM 环境错误,无需强制捕获 |
OutOfMemoryError |
| RuntimeException |
程序逻辑错误,非强制捕获(未检查异常) |
NullPointerException |
| 非运行时异常 |
外部错误,必须捕获或声明抛出(检查异常) |
IOException |
异常处理方式
1. try-catch-finally
try {
FileInputStream file = new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
} finally {
System.out.println("资源清理操作");
}
2. 抛出机制
| 关键字 |
作用 |
示例 |
throw |
在方法内主动抛出异常 |
throw new IllegalArgumentException(); |
throws |
在方法声明中指定可能抛出的异常 |
public void read() throws IOException |
equals 与 == 的区别
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // false(比较内存地址)
System.out.println(s1.equals(s2)); // true(比较内容)
| 比较对象 |
== 作用 |
equals 作用 |
| 基本类型 |
比较值是否相等 |
不可用 |
| 引用类型 |
比较内存地址是否相同 |
默认比较地址,可重写逻辑 |
hashCode 与 equals 的关系
契约规则
- 若
a.equals(b) == true,则 a.hashCode() == b.hashCode()
(必须遵守)
- 若
a.hashCode() == b.hashCode(),a.equals(b) 不一定为 true
(哈希冲突时可能发生)
// 正确重写示例
@Override
public int hashCode() {
return Objects.hash(name, age); // 基于关键字段生成
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
String vs StringBuffer vs StringBuilder
| 特性 |
String |
StringBuffer |
StringBuilder |
| 可变性 |
❌ 不可变 |
✅ 可变 |
✅ 可变 |
| 线程安全 |
✅ 安全 |
✅ (synchronized) |
❌ 不安全 |
| 性能 |
低(频繁创建新对象) |
中 |
高 |
| 适用场景 |
常量字符串 |
多线程环境字符串操作 |
单线程环境字符串操作 |
// 性能对比示例
String result = ""; // 每次拼接生成新对象
for (int i = 0; i < 10000; i++) {
result += i; // 效率极低!
}
StringBuilder sb = new StringBuilder(); // 单线程首选
for (int i = 0; i < 10000; i++) {
sb.append(i); // 内存操作,高效
}
Java 8 核心新特性
1. Lambda 表达式
// 替代匿名内部类
Runnable task = () -> System.out.println("Hello Lambda!");
new Thread(task).start();
2. 函数式接口
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b); // 单一抽象方法
}
Calculator add = (x, y) -> x + y;
System.out.println(add.calculate(3, 5)); // 输出 8
3. Stream API
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.filter(s -> !s.equals("b"))
.map(String::toUpperCase)
.forEach(System.out::println); // 输出 A, C
4. Optional 类
Optional<String> name = Optional.ofNullable(getName());
System.out.println(name.orElse("default")); // 避免 NPE
5. 其他重要特性
| 特性 |
说明 |
| 接口默认方法 |
default void log() { System.out.println("接口方法实现"); } |
| 方法引用 |
list.forEach(System.out::println) |
| 日期时间 API |
LocalDateTime.now().plusDays(1) |
| 并行数组排序 |
Arrays.parallelSort(arr) |