1. 多态的本质与核心价值
第一次接触多态概念时,我正面临一个电商系统的支付模块重构。原有代码中充斥着这样的逻辑:
java复制if (paymentType.equals("alipay")) {
// 支付宝支付处理
} else if (paymentType.equals("wechat")) {
// 微信支付处理
} else if (paymentType.equals("unionpay")) {
// 银联支付处理
}
每当新增支付方式时,就需要修改这段核心逻辑并重新测试所有分支。这种硬编码的条件判断正是多态要解决的典型问题。
多态(Polymorphism)的字面意思是"多种形态",在Java中特指同一行为在不同对象上表现出不同实现方式的能力。其核心价值在于:
- 扩展性:新增支付方式只需添加新类,无需修改现有代码
- 可维护性:支付逻辑分散在各实现类中,职责单一
- 解耦:调用方只需面向接口编程,不依赖具体实现
经过多态改造后的支付模块结构如下:
java复制interface Payment {
void pay(BigDecimal amount);
}
class Alipay implements Payment {
@Override
public void pay(BigDecimal amount) {
// 支付宝具体实现
}
}
class WechatPay implements Payment {
@Override
public void pay(BigDecimal amount) {
// 微信支付具体实现
}
}
// 使用时
Payment payment = PaymentFactory.getPayment(paymentType);
payment.pay(amount);
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 多态的实现条件与语法规范
2.1 三大必要条件
在Java培训教学中,我常把多态的实现条件比喻为"三把钥匙":
- 继承/实现关系:必须存在类继承或接口实现关系(父类/接口与子类)
- 方法重写:子类必须重写父类/接口中的方法
- 向上转型:通过父类引用指向子类对象(如
Animal dog = new Dog())
缺一不可的验证案例:
java复制class Animal {
void sound() {
System.out.println("动物发声");
}
}
class Dog extends Animal {
// 缺少方法重写
}
public class Test {
public static void main(String[] args) {
Animal animal = new Dog(); // 向上转型
animal.sound(); // 输出"动物发声",未体现多态
}
}
2.2 方法绑定机制
多态的核心在于方法调用时的动态绑定(后期绑定):
- 编译时:编译器检查父类是否有该方法(确保语法正确)
- 运行时:JVM根据实际对象类型调用对应方法实现
通过反编译可以看到方法调用的本质:
java复制// 源代码
animal.sound();
// 实际编译后的指令
invokevirtual #2 // Method Animal.sound:()V
关键提示:静态方法、私有方法和final方法不支持多态,因为它们在编译时就已经静态绑定
3. JVM层面的实现原理
3.1 方法表机制
在JVM规范中,每个类都会有一个虚方法表(vtable),存储着该类所有可被重写的方法入口地址。这是多态实现的底层数据结构支撑。
以以下类结构为例:
java复制class Animal {
void sound() { ... }
void eat() { ... }
}
class Dog extends Animal {
@Override
void sound() { ... }
}
class Cat extends Animal {
@Override
void sound() { ... }
@Override
void eat() { ... }
}
对应的虚方法表结构:
| 类 | sound方法地址 | eat方法地址 |
|---|---|---|
| Animal | Animal.sound | Animal.eat |
| Dog | Dog.sound | Animal.eat |
| Cat | Cat.sound | Cat.eat |
3.2 字节码层面的调用过程
通过javap查看关键字节码指令:
code复制aload_1 // 将对象引用压入栈
invokevirtual #3 // 调用方法(#3是常量池中的方法引用)
执行流程:
- 获取对象的实际类型(通过对象头中的类型指针)
- 查找该类型的虚方法表
- 根据方法索引定位具体方法
- 执行方法字节码
3.3 性能考量
多态调用相比静态调用会有额外开销:
- 类型检查:约2-3个CPU周期
- 方法表查找:约5-10个CPU周期
- 分支预测失败惩罚:现代CPU通过分支预测可降低影响
在热点代码中,可通过以下方式优化:
java复制// 将多态对象转换为具体类型
if (animal instanceof Dog) {
((Dog)animal).specificDogMethod();
}
4. 实战应用模式与最佳实践
4.1 策略模式实现
电商促销活动的经典实现:
java复制interface DiscountStrategy {
BigDecimal applyDiscount(BigDecimal original);
}
class NormalDiscount implements DiscountStrategy {
@Override
public BigDecimal applyDiscount(BigDecimal original) {
return original;
}
}
class VipDiscount implements DiscountStrategy {
@Override
public BigDecimal applyDiscount(BigDecimal original) {
return original.multiply(BigDecimal.valueOf(0.8));
}
}
class DiscountContext {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public BigDecimal executeStrategy(BigDecimal price) {
return strategy.applyDiscount(price);
}
}
4.2 工厂模式结合
改进后的支付工厂示例:
java复制class PaymentFactory {
public static Payment getPayment(String type) {
switch (type.toLowerCase()) {
case "alipay":
return new Alipay();
case "wechat":
return new WechatPay();
default:
throw new IllegalArgumentException("不支持的支付类型");
}
}
}
4.3 模板方法模式
报表生成的典型应用:
java复制abstract class ReportGenerator {
// 模板方法
public final void generateReport() {
prepareData();
generateHeader();
generateBody();
generateFooter();
}
protected abstract void prepareData();
protected abstract void generateBody();
private void generateHeader() {
// 公共实现
}
private void generateFooter() {
// 公共实现
}
}
class SalesReport extends ReportGenerator {
@Override
protected void prepareData() {
// 获取销售数据
}
@Override
protected void generateBody() {
// 生成销售报表主体
}
}
5. 常见误区与调试技巧
5.1 字段访问问题
容易混淆的点:字段访问不遵循多态规则
java复制class Parent {
String field = "父类字段";
}
class Child extends Parent {
String field = "子类字段";
}
Parent obj = new Child();
System.out.println(obj.field); // 输出"父类字段"
字段访问是静态绑定的,始终根据引用类型决定
5.2 构造器调用顺序
构造器中的多态陷阱:
java复制class Animal {
Animal() {
System.out.println("Animal构造器");
show();
}
void show() {
System.out.println("Animal show");
}
}
class Dog extends Animal {
Dog() {
System.out.println("Dog构造器");
}
@Override
void show() {
System.out.println("Dog show");
}
}
// 测试
new Dog();
/* 输出:
Animal构造器
Dog show // 此时Dog还未初始化完成!
Dog构造器
*/
5.3 调试技巧
- 使用断点调试时,可通过"Step Into"进入实际调用的方法实现
- 在IDEA中查看方法调用层次结构(Ctrl+Alt+H)
- 使用
getClass()方法确认运行时类型:
java复制Payment payment = PaymentFactory.getPayment("alipay");
System.out.println(payment.getClass().getName());
6. 高级应用与性能优化
6.1 多态与Lambda表达式
Java 8后,函数式接口与多态的结合:
java复制interface Validator {
boolean validate(String input);
}
class ValidatorFactory {
static Validator getEmailValidator() {
return input -> input.contains("@");
}
static Validator getPhoneValidator() {
return input -> input.matches("\\d{11}");
}
}
// 使用
Validator emailValidator = ValidatorFactory.getEmailValidator();
emailValidator.validate("test@example.com");
6.2 多态数组处理
统一处理不同类型对象的技巧:
java复制Shape[] shapes = new Shape[3];
shapes[0] = new Circle();
shapes[1] = new Rectangle();
shapes[2] = new Triangle();
for (Shape shape : shapes) {
shape.draw(); // 各自调用对应的实现
}
6.3 性能敏感场景的优化
当多态调用成为性能瓶颈时:
- 使用
final类或方法避免多态(牺牲扩展性) - 采用条件判断替代(牺牲可维护性)
- 使用
invokedynamic(Java 7+)
基准测试对比(纳秒/操作):
| 方式 | Java 8 | Java 11 | Java 17 |
|---|---|---|---|
| 直接调用 | 2.3 | 2.1 | 1.8 |
| 多态调用 | 5.7 | 4.9 | 3.5 |
| invokedynamic | 4.2 | 3.8 | 2.9 |
7. 设计模式中的多态应用
7.1 责任链模式
审批流程的典型实现:
java复制abstract class Approver {
protected Approver next;
public void setNext(Approver next) {
this.next = next;
}
public abstract void processRequest(PurchaseRequest request);
}
class Manager extends Approver {
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() <= 1000) {
// 处理逻辑
} else if (next != null) {
next.processRequest(request);
}
}
}
class Director extends Approver {
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() <= 5000) {
// 处理逻辑
} else if (next != null) {
next.processRequest(request);
}
}
}
7.2 观察者模式
事件通知系统的实现:
java复制interface Observer {
void update(String event);
}
class LogObserver implements Observer {
@Override
public void update(String event) {
System.out.println("日志记录:" + event);
}
}
class AlertObserver implements Observer {
@Override
public void update(String event) {
System.out.println("警报触发:" + event);
}
}
class EventSource {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
7.3 状态模式
订单状态管理的优雅实现:
java复制interface OrderState {
void handle(OrderContext context);
}
class NewOrderState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("处理新订单");
context.setState(new PaidState());
}
}
class PaidState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("处理已支付订单");
context.setState(new ShippedState());
}
}
class OrderContext {
private OrderState state;
public OrderContext() {
this.state = new NewOrderState();
}
public void setState(OrderState state) {
this.state = state;
}
public void process() {
state.handle(this);
}
}
8. 多态在框架中的应用解析
8.1 Spring框架中的依赖注入
Spring IoC容器的核心机制:
java复制@Service
public class UserServiceImpl implements UserService {
@Override
public User getUser(Long id) {
// 实现
}
}
@Controller
public class UserController {
@Autowired
private UserService userService; // 实际注入的是UserServiceImpl
// 使用userService
}
8.2 JUnit测试框架
测试用例的动态执行:
java复制public class TestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new MathTest("testAdd"));
suite.addTest(new MathTest("testMultiply"));
return suite;
}
}
// 框架通过反射和多态调用具体测试方法
8.3 Java集合框架
集合接口的统一操作:
java复制List<String> list = Arrays.asList("ArrayList", "LinkedList");
list = new ArrayList<>(list); // 多态赋值
list = new LinkedList<>(list); // 多态赋值
// 相同的接口方法,不同实现行为
list.add("Vector");
String first = list.get(0);
9. 多态与其它OOP特性的协同
9.1 多态与封装
封装的访问控制影响多态:
java复制class Parent {
protected void doSomething() {
System.out.println("Parent implementation");
}
}
class Child extends Parent {
@Override
public void doSomething() {
System.out.println("Child implementation");
}
}
// 测试
Parent obj = new Child();
obj.doSomething(); // 正确调用Child实现
9.2 多态与继承
方法重载与重写的区别:
java复制class Calculator {
// 重载
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
class ScientificCalculator extends Calculator {
// 重写
@Override
double add(double a, double b) {
return super.add(a, b) * 1.1;
}
}
9.3 多态与抽象类
抽象类作为多态的桥梁:
java复制abstract class Database {
abstract Connection connect();
void executeQuery(String sql) {
Connection conn = connect();
// 执行查询
}
}
class MySQLDatabase extends Database {
@Override
Connection connect() {
return DriverManager.getConnection("mysql:...");
}
}
class OracleDatabase extends Database {
@Override
Connection connect() {
return DriverManager.getConnection("oracle:...");
}
}
10. 企业级开发中的实践要点
10.1 接口设计原则
- ISP原则(接口隔离):
java复制// 错误示范
interface Worker {
void code();
void test();
void deploy();
}
// 正确拆分
interface Developer {
void code();
}
interface Tester {
void test();
}
interface DevOps {
void deploy();
}
- LSP原则(里氏替换):
java复制class Rectangle {
protected int width, height;
void setWidth(int width) {
this.width = width;
}
void setHeight(int height) {
this.height = height;
}
}
// 违反LSP的子类
class Square extends Rectangle {
@Override
void setWidth(int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
void setHeight(int height) {
super.setWidth(height);
super.setHeight(height);
}
}
10.2 多态与异常处理
方法重写时的异常规则:
java复制class Parent {
void doSomething() throws IOException {
// ...
}
}
class Child extends Parent {
@Override
void doSomething() throws FileNotFoundException {
// 允许抛出更具体的异常
}
}
class InvalidChild extends Parent {
@Override
void doSomething() throws Exception {
// 编译错误:不能抛出更通用的异常
}
}
10.3 多线程环境下的注意事项
- 状态同步问题:
java复制class Counter {
private int count;
synchronized void increment() {
count++;
}
}
class SafeCounter extends Counter {
@Override
synchronized void increment() {
super.increment();
// 额外操作
}
}
- 可见性问题:
java复制abstract class AbstractTask {
protected volatile boolean running = true;
public void stop() {
running = false;
}
public abstract void run();
}
class ConcreteTask extends AbstractTask {
@Override
public void run() {
while (running) {
// 执行任务
}
}
}
11. 现代Java中的多态演进
11.1 默认方法带来的变化
接口演化能力增强:
java复制interface Logger {
void log(String message);
default void log(String format, Object... args) {
log(String.format(format, args));
}
}
class FileLogger implements Logger {
@Override
public void log(String message) {
// 写入文件
}
// 自动继承默认方法
}
11.2 密封类(Sealed Class)的约束
Java 17引入的精确控制:
java复制public sealed class Shape permits Circle, Rectangle {
// 基类定义
}
public final class Circle extends Shape {
// 唯一允许的圆形实现
}
public final class Rectangle extends Shape {
// 唯一允许的矩形实现
}
// 编译错误
public class Triangle extends Shape {
// 不允许的扩展
}
11.3 记录类(Record)的多态
不可变数据载体的处理:
java复制record Point(int x, int y) {}
interface Shape {
Point position();
}
record Circle(Point center, int radius) implements Shape {
@Override
public Point position() {
return center;
}
}
12. 性能调优与JVM参数
12.1 方法内联优化
JVM对多态调用的优化:
code复制-XX:+PrintInlining
-XX:MaxInlineSize=35
-XX:FreqInlineSize=325
12.2 虚方法表优化
查看类的方法表布局:
code复制-XX:+PrintVtables
12.3 逃逸分析优化
栈上分配对象减少多态开销:
code复制-XX:+DoEscapeAnalysis
-XX:+EliminateAllocations
13. 多态与类型系统进阶
13.1 协变返回类型
Java 5引入的特性:
java复制class Animal {
Animal reproduce() {
return new Animal();
}
}
class Dog extends Animal {
@Override
Dog reproduce() {
return new Dog(); // 返回更具体的类型
}
}
13.2 泛型中的多态
通配符的应用:
java复制class Processor {
void process(List<? extends Number> numbers) {
for (Number n : numbers) {
System.out.println(n.doubleValue());
}
}
}
13.3 桥接方法机制
泛型擦除导致的桥接方法:
java复制class Node<T> {
public void setData(T data) {
// ...
}
}
class MyNode extends Node<Integer> {
@Override
public void setData(Integer data) {
// ...
}
}
// 编译器生成的桥接方法
public void setData(Object data) {
setData((Integer)data);
}
14. 设计模式深度结合
14.1 访问者模式的双分派
复杂对象结构的操作:
java复制interface ComputerPart {
void accept(ComputerPartVisitor visitor);
}
class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
interface ComputerPartVisitor {
void visit(Keyboard keyboard);
void visit(Monitor monitor);
}
class DisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor");
}
}
14.2 装饰器模式的透明扩展
动态添加功能:
java复制interface Coffee {
double getCost();
String getDescription();
}
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 1.0;
}
@Override
public String getDescription() {
return "Simple coffee";
}
}
abstract class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return decoratedCoffee.getCost() + 0.5;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", with milk";
}
}
14.3 组合模式的递归结构
树形结构处理:
java复制interface Component {
void operation();
}
class Leaf implements Component {
@Override
public void operation() {
System.out.println("Leaf operation");
}
}
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component component) {
children.add(component);
}
@Override
public void operation() {
for (Component child : children) {
child.operation();
}
}
}
15. 多态在微服务架构中的应用
15.1 服务接口版本化
向后兼容的实现:
java复制interface UserServiceV1 {
User getUser(Long id);
}
interface UserServiceV2 extends UserServiceV1 {
User getUser(Long id, boolean includeDeleted);
}
class UserServiceImpl implements UserServiceV2 {
@Override
public User getUser(Long id) {
return getUser(id, false);
}
@Override
public User getUser(Long id, boolean includeDeleted) {
// 实现逻辑
}
}
15.2 策略路由模式
动态服务选择:
java复制interface RoutingStrategy {
ServiceInstance select(List<ServiceInstance> instances);
}
class RandomStrategy implements RoutingStrategy {
@Override
public ServiceInstance select(List<ServiceInstance> instances) {
return instances.get(new Random().nextInt(instances.size()));
}
}
class LoadBalanceStrategy implements RoutingStrategy {
@Override
public ServiceInstance select(List<ServiceInstance> instances) {
// 根据负载选择
}
}
class Router {
private RoutingStrategy strategy;
public void setStrategy(RoutingStrategy strategy) {
this.strategy = strategy;
}
public ServiceInstance route(List<ServiceInstance> instances) {
return strategy.select(instances);
}
}
15.3 容错机制实现
弹性模式的应用:
java复制interface CircuitBreaker {
<T> T execute(Supplier<T> supplier);
}
class DefaultCircuitBreaker implements CircuitBreaker {
@Override
public <T> T execute(Supplier<T> supplier) {
try {
return supplier.get();
} catch (Exception e) {
// 处理异常
throw e;
}
}
}
class RetryCircuitBreaker implements CircuitBreaker {
private int maxAttempts;
public RetryCircuitBreaker(int maxAttempts) {
this.maxAttempts = maxAttempts;
}
@Override
public <T> T execute(Supplier<T> supplier) {
// 实现重试逻辑
}
}
16. 多态与函数式编程结合
16.1 高阶函数应用
策略的lambda实现:
java复制class PaymentProcessor {
private Function<BigDecimal, PaymentResult> strategy;
public void setStrategy(Function<BigDecimal, PaymentResult> strategy) {
this.strategy = strategy;
}
public PaymentResult processPayment(BigDecimal amount) {
return strategy.apply(amount);
}
}
// 使用
processor.setStrategy(amount -> {
// 支付宝处理逻辑
return new PaymentResult();
});
16.2 流式处理中的多态
集合操作的统一接口:
java复制List<Transaction> transactions = ...;
// 多态处理不同类型的交易
Map<TransactionType, Double> totals = transactions.stream()
.collect(Collectors.groupingBy(
Transaction::getType,
Collectors.summingDouble(Transaction::getAmount)
));
16.3 方法引用优化
简化多态调用:
java复制class StringProcessor {
private UnaryOperator<String> operation;
public void setOperation(UnaryOperator<String> operation) {
this.operation = operation;
}
public String process(String input) {
return operation.apply(input);
}
}
// 使用方法引用
processor.setOperation(String::toUpperCase);
17. 多态在测试中的应用
17.1 Mock对象的多态实现
测试替身的灵活应用:
java复制interface UserRepository {
User findById(Long id);
}
class RealUserRepository implements UserRepository {
@Override
public User findById(Long id) {
// 实际数据库查询
}
}
class MockUserRepository implements UserRepository {
@Override
public User findById(Long id) {
return new User(id, "test");
}
}
// 测试中使用Mock
UserService service = new UserService(new MockUserRepository());
17.2 参数化测试
JUnit 5的多态测试:
java复制@ParameterizedTest
@MethodSource("provideTestCases")
void testCalculator(CalculatorTestCase testCase) {
assertEquals(
testCase.expected,
calculator.calculate(testCase.input)
);
}
private static Stream<CalculatorTestCase> provideTestCases() {
return Stream.of(
new CalculatorTestCase("1+1", 2),
new CalculatorTestCase("2*3", 6)
);
}
17.3 测试框架扩展点
自定义测试行为的注入:
java复制interface TestExecutionListener {
void beforeTest(TestContext context);
void afterTest(TestContext context);
}
class TimingListener implements TestExecutionListener {
@Override
public void beforeTest(TestContext context) {
context.setAttribute("startTime", System.currentTimeMillis());
}
@Override
public void afterTest(TestContext context) {
long duration = System.currentTimeMillis() -
(long)context.getAttribute("startTime");
System.out.println("Test took " + duration + "ms");
}
}
18. 多态与反射机制
18.1 动态代理实现
AOP的基础设施:
java复制interface Service {
void serve();
}
class RealService implements Service {
@Override
public void serve() {
System.out.println("实际服务");
}
}
class LoggingProxy implements InvocationHandler {
private Object target;
public LoggingProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用前日志");
Object result = method.invoke(target, args);
System.out.println("调用后日志");
return result;
}
}
// 使用
Service proxy = (Service)Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class[]{Service.class},
new LoggingProxy(new RealService())
);
proxy.serve();
18.2 方法句柄应用
更灵活的调用方式:
java复制class PolymorphicInvoker {
private MethodHandle handle;
public PolymorphicInvoker(Method method) {
try {
handle = MethodHandles.lookup().unreflect(method);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public Object invoke(Object receiver, Object... args) {
try {
return handle.bindTo(receiver).invokeWithArguments(args);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
}
18.3 注解处理器中的多态
编译时处理的技巧:
java复制@SupportedAnnotationTypes("com.example.*")
public class MyProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
processElement(element);
}
}
return true;
}
private void processElement(Element element) {
// 多态处理不同类型的元素
if (element.getKind() == ElementKind.CLASS) {
processClass((TypeElement)element);
} else if (element.getKind() == ElementKind.METHOD) {
processMethod((ExecutableElement)element);
}
}
}
19. 多态与并发编程
19.1 线程池的任务处理
统一的任务接口:
java复制interface Task {
void execute();
}
class CPUIntensiveTask implements Task {
@Override
public void execute() {
// 计算密集型操作
}
}
class IOIntensiveTask implements Task {
@Override
public void execute() {
// IO密集型操作
}
}
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Task> tasks = Arrays.asList(new CPUIntensiveTask(), new IOIntensiveTask());
tasks.forEach(executor::submit);
19.2 Future模式的变体
不同计算策略的实现:
java复制interface Computable<A, V> {
V compute(A arg) throws InterruptedException;
}
class ExpensiveFunction implements Computable<String, BigInteger> {
@Override
public BigInteger compute(String arg) {
// 长时间计算
return new BigInteger(arg);
}
}
class Memoizer<A, V> implements Computable<A, V> {
private final Map<A, Future<V>> cache = new ConcurrentHashMap<>();
private final Computable<A, V> c;
public Memoizer(Computable<A, V> c) {
this.c = c;
}
@Override
public V compute(final A arg) throws InterruptedException {
while (true) {
Future<V> f = cache.get(arg);
if (f == null) {
FutureTask<V> ft = new FutureTask<>(() -> c.compute(arg));
f = cache.putIfAbsent(arg, ft);
if (f == null) {
f = ft;
ft.run();
}
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
}
}
}
}
19.3 并发集合的多态视图
线程安全集合的包装:
java复制class SynchronizedCollection<E> implements Collection<E> {
private final Collection<E> c;
private final Object mutex;
SynchronizedCollection(Collection<E> c) {
this.c = Objects.requireNonNull(c);
mutex = this;
}
@Override
public int size() {
synchronized (mutex) { return c.size(); }
}
@Override
public boolean add(E e) {
synchronized (mutex) { return c.add(e); }
}
// 其他方法类似实现
}
20. 多态与序列化机制
20.1 多态对象的序列化
处理继承关系的技巧:
java复制class Shape implements Serializable {
private Color color;
// ...
}
class Circle extends Shape {
private double radius;
// ...
}
// 序列化时自动处理多态类型
Shape shape = new Circle();
try (ObjectOutputStream out = new ObjectOutputStream(...)) {
out.writeObject(shape);
}
20.2 自定义序列化策略
通过多态实现不同版本处理:
java复制interface SerializationStrategy<T> {
byte[] serialize(T obj);
T deserialize(byte[] data);
}
class JsonStrategy implements SerializationStrategy<User> {
@Override
public byte[] serialize(User user) {
return new Gson().toJson(user).getBytes();
}
@Override
public User deserialize(byte[] data) {
return new Gson().fromJson(new String(data), User.class);
}
}
class ProtobufStrategy implements SerializationStrategy<User> {
@Override
public byte[] serialize(User user) {
// Protobuf序列化
}
@Override
public User deserialize(byte[] data) {
// Protobuf反序列化
}
}
20.3 外部化接口的应用
更精细的控制:
java复制class Employee implements Externalizable {
private String name;
private int age;
// 必须有无参构造器
public Employee() {}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name);
out.writeInt(age);
}
@Override
public void readExternal(ObjectInput in) throws IOException {
this.name = in.readUTF();
this.age = in.readInt();
}
}
21. 多态与元编程
21.1 注解处理器中的多态
编译时元编程:
java复制@SupportedAnnotationTypes("*")
public class PolymorphicProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
annotations.forEach(annotation ->
roundEnv.getElementsAnnotatedWith(annotation)
.forEach(this::processElement));
return false;
}
private void processElement(Element element) {
switch (element.getKind()) {
case CLASS:
processClass((TypeElement)element);
break;
case METHOD:
processMethod((ExecutableElement)element);
break;
// 其他类型处理
}
}
}
21.2 动态代码生成
运行时类创建:
java复制interface Calculator {
int calculate(int a, int b);
}
public class DynamicCalculator {
public static Calculator create(String operation) {
return (a, b) -> {
switch (operation) {
case "add": return a + b;
case "subtract": return a - b;
default: throw new UnsupportedOperationException();
}
};
}
}
21.3 表达式树处理
多态解析不同节点:
java复制interface Expr {
int eval();
}
class Constant implements Expr {
private final int value;
Constant(int value) {
this.value = value;
}
@Override
public int eval() {
return value;
}
}
class Add implements Expr {
private final Expr left, right;
Add(Expr left, Expr right) {
this.left = left;
this.right = right;
}
@Override
public int eval() {
return left.eval() + right.eval();
}
}
// 使用
Expr expr = new Add(new Constant(1), new Constant(2));
System.out.println(expr.eval()); // 输出3
22. 多态与领域驱动设计
22.1 领域事件的多态处理
事件溯源架构:
java复制interface DomainEvent {
Date occurredOn();
}
class OrderCreated implements DomainEvent {
private final OrderId orderId;
private final Date occurredOn;
@Override
public Date occurredOn() {
return occurredOn;
}
}
interface EventHandler<T extends DomainEvent> {
void handle(T event);
}
class OrderCreatedHandler implements Event
