1. 类与对象核心概念回顾
在正式探讨类与对象的进阶特性前,有必要先明确几个基础概念。类(Class)本质上是一个自定义数据类型,它封装了数据(属性)和对这些数据的操作(方法)。就像建筑设计图纸决定了房屋的结构,类定义了对象的行为模式。而对象(Object)则是类的具体实例,相当于根据图纸建造出来的实体房屋。
java复制// 简单的类定义示例
public class Smartphone {
// 属性(成员变量)
private String brand;
private double screenSize;
// 方法
public void makeCall(String number) {
System.out.println("Calling " + number);
}
}
关键理解:类与对象的关系如同模具与铸件的关系。类作为模板只存在于代码中,而对象是运行时内存中的实体。
2. 面向对象三大特性深度解析
2.1 封装的实际应用技巧
封装不仅仅是简单的private修饰符使用,更是一种设计哲学。良好的封装应该:
- 对外隐藏实现细节
- 提供清晰的访问接口
- 保持内部状态一致性
java复制public class BankAccount {
private double balance;
// 通过方法控制存取逻辑
public synchronized void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
throw new IllegalArgumentException("存款金额必须为正数");
}
}
// 提供状态查询方法
public double getBalance() {
return balance;
}
}
踩坑提醒:直接暴露集合属性是常见错误。即使返回集合,也应该返回不可修改的副本:
java复制public List<String> getItems() { return Collections.unmodifiableList(items); }
2.2 继承的合理使用原则
继承虽然强大,但过度使用会导致代码脆弱。遵循以下原则:
- 优先使用组合而非继承
- 子类必须满足"is-a"关系
- 避免超过3层的继承深度
java复制// 正确的继承示例
class Animal {
void breathe() { /*...*/ }
}
class Bird extends Animal {
void fly() { /*...*/ }
}
// 错误示例:正方形继承长方形
class Rectangle {
void setWidth(int w) { /*...*/ }
void setHeight(int h) { /*...*/ }
}
// 违反里氏替换原则
class Square extends Rectangle {
@Override
void setWidth(int w) {
super.setWidth(w);
super.setHeight(w); // 强制改变父类行为
}
}
2.3 多态的实现机制
多态的实现依赖于:
- 方法重写(Override)
- 向上转型(Upcasting)
- 动态绑定(Dynamic Binding)
java复制interface Payment {
void pay(double amount);
}
class CreditCard implements Payment {
@Override
public void pay(double amount) {
System.out.println("信用卡支付:" + amount);
}
}
class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("支付宝支付:" + amount);
}
}
// 使用多态
Payment payment = new CreditCard();
payment.pay(100.0); // 实际调用CreditCard的实现
3. 高级特性实战应用
3.1 static关键字的正确理解
static修饰的成员属于类而非对象:
- 静态变量:所有实例共享的内存空间
- 静态方法:不能访问实例成员
- 静态代码块:类加载时执行
java复制class Logger {
private static int instanceCount = 0;
public Logger() {
instanceCount++;
}
public static void printCount() {
System.out.println("已创建"+instanceCount+"个实例");
// System.out.println(this); // 错误!静态方法不能使用this
}
static {
System.out.println("Logger类初始化完成");
}
}
性能提示:频繁访问的常量应该声明为static final,避免重复创建:
java复制private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
3.2 内部类的四种形式对比
| 类型 | 特点 | 适用场景 | 内存泄漏风险 |
|---|---|---|---|
| 成员内部类 | 持有外部类引用 | 需要访问外部类成员 | 高 |
| 静态内部类 | 不持有外部类引用 | 独立工具类 | 低 |
| 局部内部类 | 方法内定义 | 临时一次性使用 | 中 |
| 匿名内部类 | 即时实现接口 | 事件监听等 | 高 |
java复制// 匿名内部类典型用法(有内存泄漏风险)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 隐式持有外部Activity引用
}
});
// 改进方案:静态内部类+弱引用
static class SafeClickListener implements View.OnClickListener {
private WeakReference<Activity> activityRef;
public SafeClickListener(Activity activity) {
this.activityRef = new WeakReference<>(activity);
}
@Override
public void onClick(View v) {
Activity activity = activityRef.get();
if (activity != null) {
// 安全操作
}
}
}
3.3 枚举类的进阶用法
枚举不仅可以表示简单常量,还能实现:
- 状态机模式
- 策略模式
- 单例模式
java复制enum HttpStatus {
OK(200, "成功"),
NOT_FOUND(404, "资源不存在"),
SERVER_ERROR(500, "服务器错误");
private final int code;
private final String desc;
HttpStatus(int code, String desc) {
this.code = code;
this.desc = desc;
}
public static HttpStatus fromCode(int code) {
for (HttpStatus status : values()) {
if (status.code == code) {
return status;
}
}
throw new IllegalArgumentException("无效状态码");
}
}
4. 对象生命周期管理
4.1 构造方法最佳实践
- 保持构造方法简单
- 避免在构造方法中调用可被重写的方法
- 考虑使用Builder模式替代多参数构造
java复制// Builder模式示例
class Computer {
private final String cpu;
private final int ram;
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
}
public static class Builder {
private String cpu;
private int ram;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder ram(int ram) {
this.ram = ram;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用方式
Computer pc = new Computer.Builder()
.cpu("i7")
.ram(16)
.build();
4.2 equals和hashCode的契约
必须同时重写这两个方法,遵守以下规则:
- 一致性:对象相等则hashCode必须相同
- 非空性:x.equals(null)必须返回false
- 对称性:x.equals(y) ⇔ y.equals(x)
java复制class Student {
private String id;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return id.equals(student.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
重要提示:使用IDE自动生成这两个方法时,要确保选择的字段确实能唯一标识对象。对于可变对象,作为hashCode依据的字段应该是不可变的。
4.3 对象拷贝的三种方式
| 方式 | 特点 | 适用场景 |
|---|---|---|
| 浅拷贝 | 复制基本类型,引用类型共享 | 简单对象 |
| 深拷贝 | 完全独立副本 | 复杂对象 |
| 克隆 | 实现Cloneable接口 | 需要精确控制 |
java复制// 深拷贝实现示例
class DeepCopyExample implements Serializable {
private List<String> data;
public DeepCopyExample deepCopy() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (DeepCopyExample) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("拷贝失败", e);
}
}
}
5. 设计模式中的类与对象
5.1 单例模式的五种实现
从简单到复杂依次为:
- 饿汉式(线程安全)
- 懒汉式(非线程安全)
- 同步方法懒汉式
- 双重检查锁定
- 静态内部类方式(推荐)
java复制// 最优的单例实现(静态内部类方式)
class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
性能对比:静态内部类方式既实现了懒加载,又无需同步开销,是最佳实践。
5.2 工厂模式的实际应用
工厂模式主要解决对象创建的解耦问题:
java复制interface PaymentFactory {
Payment create();
}
class AlipayFactory implements PaymentFactory {
@Override
public Payment create() {
return new Alipay();
}
}
class WechatPayFactory implements PaymentFactory {
@Override
public Payment create() {
return new WechatPay();
}
}
// 使用工厂
PaymentFactory factory = Config.getPaymentFactory();
Payment payment = factory.create();
5.3 观察者模式的现代实现
Java自身提供了Observable类,但更推荐使用PropertyChangeSupport:
java复制class TemperatureSensor {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private float temperature;
public void addObserver(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void setTemperature(float newTemp) {
float oldTemp = this.temperature;
this.temperature = newTemp;
pcs.firePropertyChange("temperature", oldTemp, newTemp);
}
}
6. 常见问题排查指南
6.1 NullPointerException预防
- 使用Optional包装可能为null的值
- 采用空对象模式(Null Object Pattern)
- 参数校验使用Objects.requireNonNull
java复制public void processOrder(Order order) {
Objects.requireNonNull(order, "订单不能为null");
// 业务逻辑
}
// 空对象模式示例
interface Logger {
void log(String message);
}
class NullLogger implements Logger {
@Override
public void log(String message) {
// 什么也不做
}
}
6.2 内存泄漏检测
常见泄漏场景:
- 静态集合持有对象引用
- 未关闭的资源(文件、连接)
- 匿名内部类持有外部类引用
使用工具检测:
bash复制# Java Mission Control
jcmd <pid> GC.class_histogram
# 或使用VisualVM分析堆转储
6.3 序列化问题排查
常见问题包括:
- 未实现Serializable接口
- serialVersionUID不匹配
- 包含不可序列化的成员
解决方案:
java复制class SafeSerializable implements Serializable {
private static final long serialVersionUID = 1L;
private transient SomeNonSerializableField tempField; // 使用transient排除
}
7. 现代Java中的类特性
7.1 record类的使用
Java 14引入的record类简化了数据载体类的编写:
java复制// 传统写法
class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// 省略getter, equals, hashCode等方法
}
// record写法
record Point(int x, int y) {
// 自动生成构造方法、getter、equals、hashCode等
}
7.2 sealed类(密封类)
Java 17引入的密封类可以限制继承关系:
java复制public sealed class Shape
permits Circle, Square, Rectangle {
// 基类定义
}
final class Circle extends Shape { /*...*/ }
final class Square extends Shape { /*...*/ }
non-sealed class Rectangle extends Shape { /*...*/ }
7.3 模式匹配instanceof
Java 16引入的模式匹配简化了类型检查和转换:
java复制// 传统写法
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// 模式匹配写法
if (obj instanceof String s) {
System.out.println(s.length());
}
8. 性能优化技巧
8.1 对象复用策略
- 使用对象池(如数据库连接池)
- 避免在循环中创建临时对象
- 重用不可变对象
java复制// 反面示例
for (int i = 0; i < 10000; i++) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 每次循环都创建
// ...
}
// 优化方案
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
// 或者使用ThreadLocal
private static final ThreadLocal<SimpleDateFormat> SDF =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
8.2 内存布局优化
通过字段排列减少对象大小:
java复制class Optimized {
byte b; // 1字节
int i; // 4字节
boolean flag; // 1字节
// 总大小:6字节 + 填充 = 8字节(32位JVM)
}
class Better {
int i; // 4字节
byte b; // 1字节
boolean flag; // 1字节
// 总大小:6字节(无填充)
}
8.3 反射性能优化
- 缓存Method/Field对象
- 考虑使用MethodHandle
- 对于高频调用,生成字节码(如CGLIB)
java复制// 反射调用优化示例
class ReflectOptimize {
private static final Method hashCodeMethod;
static {
try {
hashCodeMethod = Object.class.getMethod("hashCode");
hashCodeMethod.setAccessible(true); // 跳过访问检查
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public int fastHashCode(Object obj) {
try {
return (int) hashCodeMethod.invoke(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
9. 跨语言视角
9.1 Python与Java的类对比
| 特性 | Java | Python |
|---|---|---|
| 访问控制 | 严格的private/protected | 约定式(_前缀) |
| 多继承 | 不支持 | 支持 |
| 魔术方法 | 固定方法名 | __xxx__形式 |
| 动态性 | 编译时确定 | 运行时可变 |
python复制# Python类示例
class Smartphone:
def __init__(self, brand):
self._brand = brand # 约定式私有
def __str__(self):
return f"Smartphone[{self._brand}]"
9.2 JavaScript的"类"本质
ES6的class语法实质上是原型继承的语法糖:
javascript复制class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise`);
}
}
// 等价于
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise`);
};
9.3 C++与Java的对象模型差异
关键区别:
- C++对象可以在栈上分配,Java对象都在堆上
- C++支持运算符重载,Java不支持
- C++有多继承,Java只有单继承
- C++需要手动管理内存,Java有GC
cpp复制// C++类示例
class Vector {
private:
double x, y;
public:
Vector(double x, double y) : x(x), y(y) {}
// 运算符重载
Vector operator+(const Vector& other) {
return Vector(x + other.x, y + other.y);
}
};
10. 实战:设计一个健壮的类
10.1 需求分析
设计一个线程安全的缓存类,要求:
- 最大容量限制
- LRU淘汰策略
- 支持过期时间
- 高并发访问
10.2 类结构设计
java复制public class SafeCache<K, V> {
private final int maxSize;
private final Map<K, CacheEntry<V>> map;
private final Deque<K> accessQueue;
private static class CacheEntry<V> {
final V value;
final long expireTime;
CacheEntry(V value, long ttl) {
this.value = value;
this.expireTime = System.currentTimeMillis() + ttl;
}
}
}
10.3 核心方法实现
java复制public class SafeCache<K, V> {
// ...其他成员
public void put(K key, V value, long ttl) {
synchronized (this) {
evictIfNeeded();
CacheEntry<V> entry = new CacheEntry<>(value, ttl);
map.put(key, entry);
accessQueue.addLast(key);
}
}
public V get(K key) {
synchronized (this) {
CacheEntry<V> entry = map.get(key);
if (entry == null || isExpired(entry)) {
return null;
}
accessQueue.remove(key); // 更新访问顺序
accessQueue.addLast(key);
return entry.value;
}
}
private void evictIfNeeded() {
while (map.size() >= maxSize) {
K oldestKey = accessQueue.removeFirst();
map.remove(oldestKey);
}
}
}
10.4 测试用例
java复制class SafeCacheTest {
@Test
void testConcurrentAccess() throws InterruptedException {
SafeCache<String, String> cache = new SafeCache<>(100);
ExecutorService pool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
final int key = i % 100;
pool.submit(() -> {
cache.put("key"+key, "value"+key, 1000);
assertNotNull(cache.get("key"+key));
});
}
pool.shutdown();
assertTrue(pool.awaitTermination(1, TimeUnit.SECONDS));
}
}
11. 工具与框架中的类设计
11.1 Spring中的Bean管理
Spring通过IoC容器管理类的实例化:
- 单例作用域:默认配置,全局共享实例
- 原型作用域:每次请求创建新实例
- 基于注解的自动装配
java复制@Service
@Scope("prototype")
class OrderService {
@Autowired
private PaymentService paymentService;
// ...
}
11.2 MyBatis的Mapper接口原理
MyBatis通过动态代理实现接口到SQL的映射:
java复制public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(int id);
}
// 运行时生成代理类
public class MapperProxy implements InvocationHandler {
private final SqlSession sqlSession;
public Object invoke(Object proxy, Method method, Object[] args) {
// 解析注解生成SQL
// 执行数据库操作
// 返回结果
}
}
11.3 Hibernate的实体类规范
ORM框架对实体类的要求:
- 无参构造方法
- 非final类
- 持久化字段的getter/setter
- 主键标识
java复制@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
// 必须有无参构造
public Employee() {}
// getter/setter省略
}
12. 设计原则与模式应用
12.1 SOLID原则实践
- 单一职责:一个类只做一件事
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换:子类不破坏父类行为
- 接口隔离:多个专用接口优于单一通用接口
- 依赖倒置:依赖抽象而非实现
java复制// 违反单一职责的例子
class ReportGenerator {
void generateReport() { /*...*/ }
void saveToFile() { /*...*/ }
void printReport() { /*...*/ }
}
// 改进方案
class ReportGenerator {
void generate() { /*...*/ }
}
class ReportSaver {
void save(Report report) { /*...*/ }
}
class ReportPrinter {
void print(Report report) { /*...*/ }
}
12.2 组合优于继承
继承的替代方案:
- 委托(Delegation)
- 策略模式
- 装饰器模式
java复制// 使用组合替代继承
class LoggingList<E> implements List<E> {
private final List<E> innerList;
public LoggingList(List<E> innerList) {
this.innerList = innerList;
}
@Override
public void add(E e) {
System.out.println("Adding element: " + e);
innerList.add(e);
}
// 其他方法委托给innerList
}
12.3 迪米特法则应用
最小知识原则实践:
- 减少类之间的耦合
- 只与直接朋友通信
- 避免链式调用
java复制// 违反迪米特法则
class Client {
void doSomething(Server server) {
Database db = server.getDatabase();
Table table = db.getTable("users");
Row row = table.getRow(123);
// 直接操作row
}
}
// 改进方案
class Server {
void processClientRequest(ClientRequest request) {
// 内部处理所有细节
}
}
13. 代码质量保障
13.1 单元测试策略
针对类的测试要点:
- 测试公有接口,不测试私有方法
- 每个测试用例验证一个行为
- 使用Mock隔离依赖
java复制class ShoppingCartTest {
@Test
void shouldCalculateTotal() {
ShoppingCart cart = new ShoppingCart();
cart.addItem(new Item("Book", 50.0));
cart.addItem(new Item("Pen", 10.0));
assertEquals(60.0, cart.getTotal(), 0.001);
}
@Test
void shouldApplyDiscount() {
ShoppingCart cart = new ShoppingCart();
cart.addItem(new Item("Laptop", 1000.0));
DiscountStrategy discount = mock(DiscountStrategy.class);
when(discount.apply(anyDouble())).thenReturn(900.0);
cart.setDiscountStrategy(discount);
assertEquals(900.0, cart.getTotal(), 0.001);
}
}
13.2 静态代码分析
常用检查项:
- 圈复杂度过高
- 过大的类
- 过长的参数列表
- 重复代码
使用工具:
bash复制# SpotBugs示例
mvn spotbugs:check
# 或使用SonarQube进行持续检测
13.3 重构技巧
常见重构手法:
- 提取方法
- 内联临时变量
- 用多态替代条件判断
- 引入参数对象
java复制// 重构前
class OrderProcessor {
void process(Order order) {
if (order.getType() == OrderType.NORMAL) {
// 20行处理逻辑
} else if (order.getType() == OrderType.URGENT) {
// 15行处理逻辑
}
}
}
// 重构后
abstract class OrderHandler {
abstract void handle(Order order);
}
class NormalOrderHandler extends OrderHandler { /*...*/ }
class UrgentOrderHandler extends OrderHandler { /*...*/ }
class OrderProcessor {
private Map<OrderType, OrderHandler> handlers;
void process(Order order) {
handlers.get(order.getType()).handle(order);
}
}
14. 领域驱动设计中的类
14.1 实体与值对象
关键区别:
| 特征 | 实体(Entity) | 值对象(Value Object) |
|---|---|---|
| 标识 | 有唯一ID | 通过属性值区分 |
| 可变性 | 可变 | 通常不可变 |
| 生命周期 | 需要持久化 | 可随时创建/丢弃 |
java复制// 实体示例
class User {
private UUID id; // 唯一标识
private String name;
// 其他属性和行为
}
// 值对象示例
class Address {
private final String city;
private final String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
// 没有setter方法
}
14.2 聚合根设计
聚合根是领域模型的入口点:
- 负责维护聚合内的一致性
- 外部只能通过聚合根访问内部对象
- 一个聚合一个事务边界
java复制class Order implements AggregateRoot {
private String orderId;
private List<OrderItem> items;
private Customer customer;
public void addItem(Product product, int quantity) {
// 业务规则校验
if (items.stream().anyMatch(i -> i.getProductId().equals(product.getId()))) {
throw new IllegalStateException("产品已存在");
}
items.add(new OrderItem(product, quantity));
}
// 其他方法确保业务规则
}
14.3 领域服务与应用服务
职责划分:
- 领域服务:包含业务逻辑的无状态服务
- 应用服务:协调领域对象和技术设施
java复制// 领域服务示例
class TransferService {
public void transfer(Account from, Account to, Money amount) {
from.withdraw(amount);
to.deposit(amount);
// 可能触发领域事件
}
}
// 应用服务示例
class BankingAppService {
private TransferService transferService;
private AccountRepository accountRepo;
@Transactional
public void transferMoney(String fromId, String toId, BigDecimal amount) {
Account from = accountRepo.findById(fromId);
Account to = accountRepo.findById(toId);
transferService.transfer(from, to, new Money(amount));
accountRepo.save(from);
accountRepo.save(to);
}
}
15. 函数式编程与类设计
15.1 不可变类设计
创建不可变类的规则:
- 所有字段final
- 私有字段,无setter
- 子类不能覆盖方法
- 返回可变对象的防御性拷贝
java复制public final class ImmutablePoint {
private final double x;
private final double y;
private final List<String> labels;
public ImmutablePoint(double x, double y, List<String> labels) {
this.x = x;
this.y = y;
this.labels = Collections.unmodifiableList(new ArrayList<>(labels));
}
public List<String> getLabels() {
return Collections.unmodifiableList(labels);
}
}
15.2 高阶函数与类结合
在类中使用函数式接口:
java复制class DataProcessor {
private Function<String, String> inputTransformer;
private Predicate<String> validator;
public DataProcessor(Function<String, String> transformer,
Predicate<String> validator) {
this.inputTransformer = transformer;
this.validator = validator;
}
public String process(String input) {
String transformed = inputTransformer.apply(input);
if (!validator.test(transformed)) {
throw new IllegalArgumentException("无效输入");
}
return transformed.toUpperCase();
}
}
// 使用
DataProcessor processor = new DataProcessor(
s -> s.trim(),
s -> s.length() > 0
);
15.3 流式API设计
实现流畅接口的技巧:
- 方法返回this
- 分离配置和执行方法
- 使用中间对象保存状态
java复制public class QueryBuilder {
private String table;
private List<String> columns = new ArrayList<>();
private List<String> conditions = new ArrayList<>();
public QueryBuilder from(String table) {
this.table = table;
return this;
}
public QueryBuilder select(String... columns) {
this.columns.addAll(Arrays.asList(columns));
return this;
}
public QueryBuilder where(String condition) {
this.conditions.add(condition);
return this;
}
public String build() {
return "SELECT " + String.join(", ", columns) +
" FROM " + table +
(conditions.isEmpty() ? "" :
" WHERE " + String.join(" AND ", conditions));
}
}
// 使用方式
String sql = new QueryBuilder()
.from("users")
.select("name", "email")
.where("age > 18")
.where("status = 'active'")
.build();
16. 并发编程中的类设计
16.1 线程安全类设计
实现线程安全的几种方式:
- 无状态(最佳方案)
- 不可变对象
- 使用锁(synchronized或Lock)
- 线程封闭(如ThreadLocal)
java复制// 使用synchronized的计数器
class SynchronizedCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
// 使用AtomicInteger的更优方案
class AtomicCounter {
private final AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
16.2 并发工具类应用
Java并发包中的实用类:
- CountDownLatch:等待多个任务完成
- CyclicBarrier:线程同步点
- Semaphore:控制资源访问
- ConcurrentHashMap:线程安全Map
java复制class CacheLoader {
private final ConcurrentHashMap<String, String> cache = new ConcurrentHashMap<>();
private final ExecutorService executor = Executors.newFixedThreadPool(4);
public String get(String key) {
return cache.computeIfAbsent(key, k -> {
// 模拟耗时加载
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "value_for_" + k;
});
}
public CompletableFuture<Void> preload(List<String> keys) {
CountDownLatch latch = new CountDownLatch(keys.size());
keys.forEach(key ->
executor.submit(() -> {
get(key);
latch.countDown();
})
);
return CompletableFuture.runAsync(() -> {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
}
16.3 异步编程模式
现代异步编程方式:
- Future模式
- Callback模式
- Promise/Future组合(CompletableFuture)
- 响应式编程(Reactive Streams)
java复制class AsyncService {
private final ExecutorService executor = Executors.newCachedThreadPool();
public CompletableFuture<String> fetchData(String url) {
return CompletableFuture.supplyAsync(() -> {
// 模拟网络请求
try {
Thread.sleep(500);
return "Data from " + url;
} catch (InterruptedException e) {
throw new CompletionException(e);
}
}, executor);
}
public CompletableFuture<Void> processMultiple(List<String> urls) {
List<CompletableFuture<String>> futures = urls.stream()
.map(this::fetchData)
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()))
.thenAccept(results -> {
System.out.println("Got " + results.size() + " results");
// 进一步处理
});
}
}
17. 元编程与反射进阶
17.1 注解处理器应用
编译时处理注解的典型流程:
- 定义注解类型
- 实现AbstractProcessor
- 注册处理器(META-INF/services)
- 生成代码或验证逻辑
java复制@SupportedAnnotationTypes("com.example.NotNull")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class NotNullProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(NotNull.class)) {
if (element.getKind() == ElementKind.FIELD) {
VariableElement field = (VariableElement) element;
String fieldName = field.getSimpleName().toString();
String className = field.getEnclosingElement().toString();
processingEnv.getMessager().printMessage(
Diagnostic.Kind.NOTE,
"Found @NotNull field: " + className + "." + fieldName);
}
}
return true;
}
}
17.2 动态代理高级用法
实现AOP等横切关注点:
java复制class LoggingProxy implements InvocationHandler {
private final Object target;
private final Logger logger;
public LoggingProxy(Object target, Logger logger) {
this.target = target;
this.logger = logger;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
logger.info("Entering " + method.getName());
long start = System.nanoTime();
try {
Object result = method.invoke(target, args);
logger.info("Exiting " + method.getName() + " with " + result);
return result;
} catch (Exception e) {
logger.severe("Exception in " + method.getName() + ": " + e);
throw e;
} finally {
long duration = System.nanoTime() - start;
logger.info(method.getName() + " took " + duration + " ns");
}
}
@SuppressWarnings("unchecked")
public static <T> T create(Class<T> interfaceType, T target, Logger logger) {
return (T) Proxy.newProxyInstance(
interfaceType.getClassLoader(),
new Class
