1. Java多态的本质与实现机制
多态是面向对象编程的三大特性之一,它允许不同类的对象对同一消息做出响应。在Java中,多态主要通过方法重写(Override)和接口实现来体现。其核心在于JVM的方法调用机制——动态绑定(Dynamic Binding)。
当调用一个对象的方法时,JVM会根据对象的实际类型(而非引用类型)来决定调用哪个方法实现。这个决策过程发生在运行时,具体通过方法表(Method Table)实现。每个类都会维护一个方法表,其中包含该类所有可访问方法的实际入口地址。
关键理解:父类引用指向子类对象时(如 Animal dog = new Dog()),编译期检查引用类型的方法是否存在,运行时则根据实际对象类型调用具体实现。
动态绑定的实现细节:
- 类加载阶段:JVM为每个类构建方法表
- 方法调用时:通过对象头中的类型指针找到实际类的方法表
- 方法查找:根据方法签名定位具体方法入口
- 执行:跳转到目标方法字节码
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 多态的类型与典型应用场景
2.1 编译时多态(静态多态)
通过方法重载(Overload)实现,在编译期即可确定具体调用的方法。典型特征:
- 方法名相同
- 参数列表不同(类型、顺序、数量)
- 与返回值类型无关
java复制class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
2.2 运行时多态(动态多态)
通过继承和方法重写实现,运行期才能确定具体方法。必要条件:
- 继承关系
- 子类重写父类方法
- 父类引用指向子类对象
java复制class Animal {
void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
@Override
void sound() { System.out.println("Bark"); }
}
// 使用
Animal myPet = new Dog();
myPet.sound(); // 输出"Bark"
2.3 接口多态
通过接口实现更灵活的抽象,是Java实现多重继承的主要方式。特点:
- 类可以实现多个接口
- 接口可以多继承
- JDK8+支持默认方法和静态方法
java复制interface Flyable {
default void fly() {
System.out.println("Flying");
}
}
class Bird implements Flyable {
// 可选择重写或使用默认实现
}
// 使用
Flyable creature = new Bird();
creature.fly();
3. 多态的高级特性与底层原理
3.1 方法分派机制
Java采用单分派机制,即根据接收者的实际类型进行方法选择。分派类型包括:
- 静态分派:重载方法调用(编译期确定)
- 动态分派:重写方法调用(运行期确定)
示例分析:
java复制class Wine {
String name() { return "wine"; }
}
class JNC extends Wine {
@Override String name() { return "JNC"; }
}
class Test {
void printName(Wine w) {
System.out.println(w.name());
}
public static void main(String[] args) {
Test t = new Test();
t.printName(new JNC()); // 输出"JNC"
}
}
3.2 虚方法与非虚方法
- 虚方法:可被重写的方法(动态绑定)
- 非虚方法:不可被重写的方法(静态绑定),包括:
- private方法
- final方法
- static方法
- 构造器
- 父类调用的super.method()
3.3 方法表结构
JVM为每个类维护一个虚方法表(vtable),存储方法的实际入口地址。子类方法表包含:
- 从父类继承的方法(可能被重写)
- 子类新增的方法
- 实现接口的方法
方法调用字节码解析:
- invokevirtual:虚方法调用
- invokeinterface:接口方法调用
- invokespecial:构造器/private/super调用
- invokestatic:静态方法调用
4. 多态在框架设计中的典型应用
4.1 Spring框架的依赖注入
Spring容器通过多态实现松耦合:
java复制public interface UserService {
void save(User user);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public void save(User user) { /* 实现 */ }
}
// 使用处
@Autowired
private UserService userService; // 实际注入的是UserServiceImpl
4.2 Java集合框架
集合接口与实现类的多态关系:
java复制List<String> list = new ArrayList<>(); // 多态声明
list = new LinkedList<>(); // 可随时替换实现
4.3 模板方法模式
父类定义算法骨架,子类实现具体步骤:
java复制abstract class Game {
// 模板方法
final void play() {
initialize();
startPlay();
endPlay();
}
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
}
class Cricket extends Game {
/* 实现抽象方法 */
}
5. 多态使用中的常见问题与解决方案
5.1 类型转换异常
错误示例:
java复制Object obj = "Hello";
Integer num = (Integer) obj; // ClassCastException
安全转换方案:
java复制if (obj instanceof Integer) {
Integer num = (Integer) obj;
}
5.2 方法重写规则违反
常见错误:
- 访问权限缩小(如父类protected,子类改为private)
- 返回类型不兼容
- 抛出更宽泛的检查异常
正确实践:使用@Override注解让编译器检查重写规则
5.3 多态与字段访问
字段访问是静态绑定的(编译期确定):
java复制class Parent {
String field = "Parent";
}
class Child extends Parent {
String field = "Child";
}
Parent obj = new Child();
System.out.println(obj.field); // 输出"Parent"
5.4 构造器中的多态问题
在构造器中调用可重写方法是危险操作:
java复制class Parent {
Parent() {
print(); // 调用子类重写的方法
}
void print() { System.out.println("Parent"); }
}
class Child extends Parent {
int value = 10;
@Override void print() {
System.out.println(value); // 输出0(未初始化)
}
}
6. 多态性能优化实践
6.1 虚方法内联优化
JVM通过类型继承关系分析(CHA)对虚方法进行去虚拟化:
- 如果发现某个虚方法只有一个实现,会直接内联调用
- 使用final方法帮助JVM优化
6.2 接口调用优化
JDK8引入的默认方法会带来性能考量:
- 接口方法调用比类方法调用稍慢
- 考虑使用抽象类替代纯接口(当需要共享代码时)
6.3 多态与数组存储
数组协变带来的类型安全问题:
java复制Object[] array = new String[10];
array[0] = 1; // 运行时抛出ArrayStoreException
解决方案:
- 使用泛型集合代替数组
- 必要时进行类型检查
7. 多态在Java新特性中的演进
7.1 密封类(Sealed Class)
JDK17引入的密封类可以精确控制继承关系:
java复制public sealed class Shape
permits Circle, Square, Rectangle { /*...*/ }
7.2 模式匹配(Pattern Matching)
JDK16+的instanceof模式匹配简化多态代码:
java复制if (obj instanceof String s) {
System.out.println(s.length()); // 直接使用s
}
7.3 记录类(Record)
记录类的多态特性:
java复制record Point(int x, int y) {}
// 多态使用
Object obj = new Point(1, 2);
if (obj instanceof Point(int x, int y)) {
System.out.println(x + "," + y);
}
8. 多态与设计模式的深度结合
8.1 策略模式
通过多态实现算法族的动态替换:
java复制interface SortStrategy {
void sort(int[] arr);
}
class QuickSort implements SortStrategy { /*...*/ }
class MergeSort implements SortStrategy { /*...*/ }
class Sorter {
private SortStrategy strategy;
void setStrategy(SortStrategy s) {
this.strategy = s;
}
void executeSort(int[] arr) {
strategy.sort(arr);
}
}
8.2 观察者模式
基于接口的多态通知机制:
java复制interface Observer {
void update(String event);
}
class LogObserver implements Observer { /*...*/ }
class AlertObserver implements Observer { /*...*/ }
class Subject {
private List<Observer> observers = new ArrayList<>();
void notifyObservers(String event) {
for (Observer o : observers) {
o.update(event); // 多态调用
}
}
}
8.3 访问者模式
双重分派实现复杂对象结构操作:
java复制interface Visitor {
void visit(ElementA a);
void visit(ElementB b);
}
interface Element {
void accept(Visitor v);
}
class ElementA implements Element {
@Override
public void accept(Visitor v) {
v.visit(this); // 回调Visitor的具体方法
}
}
9. 多态在Java企业开发中的实战技巧
9.1 依赖倒置原则实践
高层模块不应依赖低层模块,二者都应依赖抽象:
java复制// 不好的实现
class ReportService {
private MySQLDatabase db;
void generate() {
db.query(...);
}
}
// 好的实现
class ReportService {
private Database db; // 接口依赖
void generate() {
db.query(...);
}
}
9.2 测试中的多态应用
使用Mock对象进行单元测试:
java复制interface PaymentGateway {
boolean process(Payment p);
}
class MockPaymentGateway implements PaymentGateway {
@Override
public boolean process(Payment p) {
return true; // 测试实现
}
}
// 测试用例
@Test
void testOrder() {
Order order = new Order(new MockPaymentGateway());
assertTrue(order.checkout());
}
9.3 插件架构实现
通过多态支持动态扩展:
java复制interface Plugin {
void execute();
}
class PluginManager {
void loadPlugins() {
ServiceLoader<Plugin> plugins = ServiceLoader.load(Plugin.class);
plugins.forEach(Plugin::execute);
}
}
10. 多态相关的JVM参数调优
10.1 方法内联控制
- -XX:+PrintInlining:打印内联决策
- -XX:MaxInlineSize=35:设置可内联方法的最大字节码大小
- -XX:FreqInlineSize=325:频繁执行方法的内联大小限制
10.2 虚方法调用优化
- -XX:+UseCHA:启用类型继承关系分析
- -XX:+AggressiveOpts:启用激进优化(包括虚方法)
10.3 去虚拟化控制
- -XX:+PrintDevirtualization:打印去虚拟化日志
- -XX:-UseTypeProfile:禁用类型分析(测试用)
11. 多态与Java内存模型
11.1 对象头中的类型指针
每个Java对象头包含指向类元数据的指针,这是多态的基础。在64位JVM中:
- 开启压缩指针(-XX:+UseCompressedOops)时占4字节
- 关闭压缩指针时占8字节
11.2 方法区与多态
类的元数据(包括方法表)存储在方法区(Metaspace),关键参数:
- -XX:MetaspaceSize=64m:初始大小
- -XX:MaxMetaspaceSize=256m:最大大小
11.3 多态与GC影响
多态引用可能影响GC效率:
- 多态引用使得逃逸分析更复杂
- 接口类型数组比具体类型数组更难优化
- 考虑在性能关键路径使用具体类型
12. 多态在Java并发编程中的应用
12.1 线程工厂模式
通过多态创建不同类型的线程:
java复制interface ThreadFactory {
Thread newThread(Runnable r);
}
class DaemonThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
12.2 回调机制
异步编程中的多态回调:
java复制interface Callback {
void onComplete(Result result);
void onError(Exception e);
}
class AsyncTask {
void execute(Callback callback) {
new Thread(() -> {
try {
Result r = doWork();
callback.onComplete(r);
} catch (Exception e) {
callback.onError(e);
}
}).start();
}
}
12.3 锁策略抽象
通过多态实现可替换的锁策略:
java复制interface LockStrategy {
void lock();
void unlock();
}
class ReentrantLockStrategy implements LockStrategy {
private final ReentrantLock lock = new ReentrantLock();
@Override
public void lock() { lock.lock(); }
@Override
public void unlock() { lock.unlock(); }
}
13. 多态与Java序列化
13.1 多态序列化问题
反序列化时需要正确恢复对象类型:
java复制class Animal implements Serializable { /*...*/ }
class Dog extends Animal { /*...*/ }
// 序列化
Animal a = new Dog();
serialize(a);
// 反序列化
Animal a2 = deserialize(); // 需要能正确识别实际类型为Dog
13.2 解决方案
- 使用serialVersionUID保持版本兼容
- 考虑使用Externalizable进行更精确控制
- 或者使用JSON/XML等文本序列化方案
13.3 类型标识技巧
在序列化数据中包含类型信息:
java复制enum AnimalType { DOG, CAT }
class Animal {
AnimalType type;
// ...
}
class Dog extends Animal {
Dog() { type = AnimalType.DOG; }
}
14. 多态与Java反射
14.1 反射调用多态方法
通过反射调用方法仍然保持多态特性:
java复制class Parent {
void method() { System.out.println("Parent"); }
}
class Child extends Parent {
@Override void method() { System.out.println("Child"); }
}
Parent obj = new Child();
Method m = Parent.class.getDeclaredMethod("method");
m.invoke(obj); // 输出"Child"
14.2 反射性能考量
反射方法调用比普通虚方法调用更慢:
- 正常虚方法调用:约2-3个时钟周期
- 反射调用:约1000+时钟周期
- 可以考虑方法句柄(MethodHandle)优化
14.3 方法句柄优化
JDK7引入的MethodHandle可以提供接近原生调用的性能:
java复制class MyClass {
void print(String s) { System.out.println(s); }
}
// 获取方法句柄
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(
MyClass.class, "print",
MethodType.methodType(void.class, String.class)
);
// 调用
MyClass obj = new MyClass();
mh.invokeExact(obj, "Hello");
15. 多态在Java函数式编程中的应用
15.1 函数式接口多态
通过不同的Lambda实现相同接口:
java复制Function<String, Integer> parser1 = Integer::parseInt;
Function<String, Integer> parser2 = s -> s.length();
List<String> inputs = Arrays.asList("123", "hello");
inputs.stream()
.map(parser1) // 第一种解析方式
.forEach(System.out::println);
inputs.stream()
.map(parser2) // 第二种解析方式
.forEach(System.out::println);
15.2 策略模式Lambda实现
用Lambda简化策略模式:
java复制interface ValidationStrategy {
boolean validate(String s);
}
// 传统实现
class LengthValidator implements ValidationStrategy {
@Override public boolean validate(String s) {
return s.length() > 6;
}
}
// Lambda实现
ValidationStrategy lengthValidator = s -> s.length() > 6;
15.3 高阶函数多态
函数作为参数和返回值:
java复制Function<Function<String, Integer>, List<Integer>>
parseAll = parser -> inputs.stream()
.map(parser)
.collect(Collectors.toList());
16. 多态与Java模块系统
16.1 模块化与服务加载
模块系统中通过provides/uses声明服务:
java复制// 服务接口模块
module service.api {
exports com.example.service;
}
// 服务实现模块
module service.impl {
requires service.api;
provides com.example.service.MyService
with com.example.impl.MyServiceImpl;
}
// 客户端模块
module client {
requires service.api;
uses com.example.service.MyService;
}
16.2 模块间的多态调用
通过接口跨模块通信:
java复制ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class);
MyService service = loader.findFirst().orElseThrow();
service.doSomething();
16.3 模块反射限制
模块系统对反射的影响:
- 默认无法反射访问非导出包
- 需要添加opens指令开放反射权限
- 考虑使用MethodHandles的private访问能力
17. 多态在Java性能分析中的体现
17.1 方法调用树分析
使用JProfiler等工具观察多态方法调用:
- 识别高频虚方法调用
- 分析调用链路上的性能瓶颈
- 检查是否有不必要的多态层级
17.2 JIT编译日志分析
通过-XX:+PrintCompilation查看方法编译:
log复制 42 3 java.lang.String::hashCode (55 bytes)
43 4 java.util.HashMap::hash (20 bytes)
44 2% com.example.MyService::process @ 4 (25 bytes)
%表示包含多态调用的方法
17.3 类型画像(Type Profiling)
JVM会收集类型信息优化多态调用:
- -XX:+PrintTypeProfile:打印类型画像
- 高频单态调用会被去虚拟化
- 多态调用点会记录常见接收者类型
18. 多态与Java注解处理
18.1 注解处理器中的多态
通过多态处理不同注解:
java复制@SupportedAnnotationTypes("*")
class MyProcessor extends AbstractProcessor {
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment env
) {
for (TypeElement te : annotations) {
processAnnotation(te, env);
}
return true;
}
void processAnnotation(TypeElement te, RoundEnvironment env) {
// 多态处理
}
}
18.2 元注解的多态应用
通过注解继承实现多态行为:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface PolymorphicAnnotation {
Class<?> value();
}
@PolymorphicAnnotation(MyHandler.class)
public @interface MyAnnotation {}
18.3 运行时注解处理
通过反射实现注解多态:
java复制interface AnnotationHandler<T extends Annotation> {
void handle(T annotation);
}
class MyAnnotationHandler implements AnnotationHandler<MyAnnotation> {
@Override
public void handle(MyAnnotation annotation) {
// 具体处理
}
}
19. 多态在Java安全编程中的应用
19.1 权限检查的多态实现
通过不同策略检查权限:
java复制interface AccessPolicy {
boolean check(User user, Resource resource);
}
class RoleBasedPolicy implements AccessPolicy { /*...*/ }
class TimeBasedPolicy implements AccessPolicy { /*...*/ }
class AccessManager {
private AccessPolicy policy;
void setPolicy(AccessPolicy p) { policy = p; }
boolean grantAccess(User u, Resource r) {
return policy.check(u, r);
}
}
19.2 加密策略多态
可插拔的加密算法:
java复制interface Encryptor {
byte[] encrypt(byte[] data);
byte[] decrypt(byte[] data);
}
class AESEncryptor implements Encryptor { /*...*/ }
class RSAEncryptor implements Encryptor { /*...*/ }
19.3 安全审计日志
多态审计处理器:
java复制interface AuditHandler {
void log(AuditEvent event);
}
class DatabaseAuditHandler implements AuditHandler { /*...*/ }
class FileAuditHandler implements AuditHandler { /*...*/ }
20. 多态与Java本地方法交互
20.1 JNI中的多态调用
通过JNI调用Java虚方法:
c复制jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;");
jstring result = (*env)->CallObjectMethod(env, obj, mid);
20.2 类型签名注意事项
JNI方法签名必须精确匹配:
- 父类方法:"(参数签名)返回签名"
- 重写方法:必须完全一致
- 接口方法:特殊处理
20.3 性能优化建议
- 缓存jmethodID(非静态字段)
- 对高频调用考虑使用Critical Native
- 避免过度跨JNI边界调用
21. 多态在Java网络编程中的应用
21.1 协议处理的多态实现
不同协议的不同处理器:
java复制interface ProtocolHandler {
void handle(ByteBuffer data);
}
class HttpHandler implements ProtocolHandler { /*...*/ }
class TcpHandler implements ProtocolHandler { /*...*/ }
class Server {
private ProtocolHandler handler;
void setHandler(ProtocolHandler h) { handler = h; }
void process(ByteBuffer data) {
handler.handle(data);
}
}
21.2 NIO事件处理
Selector多路复用的多态应用:
java复制interface ChannelHandler {
void handle(SelectionKey key);
}
class ReadHandler implements ChannelHandler { /*...*/ }
class WriteHandler implements ChannelHandler { /*...*/ }
class Reactor {
private Map<SelectionKey, ChannelHandler> handlers = new HashMap<>();
void register(SelectionKey key, ChannelHandler h) {
handlers.put(key, h);
}
void dispatch(SelectionKey key) {
handlers.get(key).handle(key);
}
}
21.3 异步回调模型
基于接口的异步处理:
java复制interface CompletionHandler<V> {
void completed(V result);
void failed(Throwable exc);
}
class FileReader {
void readAsync(Path path, CompletionHandler<String> handler) {
new Thread(() -> {
try {
String content = Files.readString(path);
handler.completed(content);
} catch (IOException e) {
handler.failed(e);
}
}).start();
}
}
22. 多态与Java内存管理
22.1 对象池的多态设计
通用对象池接口:
java复制interface ObjectPool<T> {
T borrowObject();
void returnObject(T obj);
}
class GenericObjectPool<T> implements ObjectPool<T> {
private final Supplier<T> factory;
private final Queue<T> pool = new ConcurrentLinkedQueue<>();
GenericObjectPool(Supplier<T> factory) {
this.factory = factory;
}
@Override
public T borrowObject() {
T obj = pool.poll();
return obj != null ? obj : factory.get();
}
@Override
public void returnObject(T obj) {
pool.offer(obj);
}
}
22.2 内存分配策略
通过多态选择分配策略:
java复制interface MemoryAllocator {
ByteBuffer allocate(int size);
}
class HeapAllocator implements MemoryAllocator { /*...*/ }
class DirectAllocator implements MemoryAllocator { /*...*/ }
22.3 弱引用策略
不同引用类型的多态处理:
java复制interface ReferenceHandler {
void handle(Object referent);
}
class WeakHandler implements ReferenceHandler {
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
void register(Object obj) {
new WeakReference<>(obj, queue);
}
@Override
public void handle(Object referent) {
System.out.println("Cleaning " + referent);
}
}
23. 多态与Java国际化
23.1 多语言资源加载
通过Locale选择资源实现:
java复制interface MessageProvider {
String getMessage(String key);
}
class DatabaseMessageProvider implements MessageProvider { /*...*/ }
class PropertyMessageProvider implements MessageProvider { /*...*/ }
class I18nService {
private Map<Locale, MessageProvider> providers = new HashMap<>();
void register(Locale locale, MessageProvider provider) {
providers.put(locale, provider);
}
String getMessage(Locale locale, String key) {
return providers.get(locale).getMessage(key);
}
}
23.2 日期格式策略
不同地区的日期格式化:
java复制interface DateFormatter {
String format(Date date);
}
class ChinaDateFormatter implements DateFormatter { /*...*/ }
class USADateFormatter implements DateFormatter { /*...*/ }
23.3 货币转换处理
多币种转换策略:
java复制interface CurrencyConverter {
BigDecimal convert(BigDecimal amount, Currency to);
}
class FixedRateConverter implements CurrencyConverter { /*...*/ }
class LiveRateConverter implements CurrencyConverter { /*...*/ }
24. 多态在Java图形界面中的应用
24.1 跨平台UI组件
通过工厂方法创建平台相关组件:
java复制interface Button {
void render();
void onClick(Runnable action);
}
class WindowsButton implements Button { /*...*/ }
class MacButton implements Button { /*...*/ }
interface GUIFactory {
Button createButton();
}
class WindowsFactory implements GUIFactory { /*...*/ }
class MacFactory implements GUIFactory { /*...*/ }
24.2 布局管理器
可替换的布局策略:
java复制interface LayoutManager {
void layout(Container parent);
}
class BorderLayoutManager implements LayoutManager { /*...*/ }
class GridLayoutManager implements LayoutManager { /*...*/ }
24.3 事件处理模型
多态事件监听器:
java复制interface EventListener<T extends Event> {
void handle(T event);
}
class MouseClickListener implements EventListener<MouseEvent> { /*...*/ }
class KeyPressListener implements EventListener<KeyEvent> { /*...*/ }
25. 多态与Java元编程
25.1 动态代理
JDK动态代理的多态应用:
java复制interface Service {
void serve();
}
class RealService implements Service {
@Override public void serve() {
System.out.println("Real service");
}
}
class ProxyHandler implements InvocationHandler {
private final Object target;
ProxyHandler(Object target) { this.target = target; }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before call");
Object result = method.invoke(target, args);
System.out.println("After call");
return result;
}
}
// 使用
Service proxy = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class[]{Service.class},
new ProxyHandler(new RealService())
);
proxy.serve();
25.2 字节码增强
通过ASM等工具修改字节码实现多态增强:
java复制class MethodAdapter extends MethodVisitor {
@Override
public void visitMethodInsn(
int opcode, String owner,
String name, String desc, boolean itf
) {
// 修改虚方法调用
if (name.equals("targetMethod")) {
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
"Interceptor",
"intercept",
desc, false
);
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
}
25.3 运行时代码生成
动态生成实现类:
java复制interface DynamicService {
String process(String input);
}
public class RuntimeCompiler {
public static DynamicService createService() throws Exception {
String className = "DynamicServiceImpl";
String source = "class " + className + " implements DynamicService {" +
" public String process(String input) {" +
" return input.toUpperCase();" +
" }" +
"}";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager =
compiler.getStandardFileManager(null, null, null);
JavaFileObject javaObject = new SimpleJavaFileObject(
URI.create(className + ".java"),
JavaFileObject.Kind.SOURCE
) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
};
compiler.getTask(null, fileManager, null, null, null,
Arrays.asList(javaObject)).call();
Class<?> clazz = Class.forName(className);
return (DynamicService) clazz.newInstance();
}
}
26. 多态与Java测试驱动开发
26.1 测试替身(Test Double)
通过多态实现测试替身:
java复制interface Database {
User findUser(String id);
}
class RealDatabase implements Database { /*...*/ }
class MockDatabase implements Database {
@Override
public User findUser(String id) {
return new User("test", "Test User");
}
}
// 测试用例
@Test
void testWithMock() {
UserService service = new UserService(new MockDatabase());
User user = service.getUser("123");
assertEquals("Test User", user.getName());
}
26.2 参数化测试
多态测试数据提供:
java复制interface TestDataProvider {
Object[] provide();
}
class UserProvider implements TestDataProvider {
@Override
public Object[] provide() {
return new Object[]{
new Object[]{new User("admin", "Admin"), true},
new Object[]{new User("guest", "Guest"), false}
};
}
}
class UserServiceTest {
@ParameterizedTest
@ArgumentsSource(UserProvider.class)
void testHasAdminAccess(User user, boolean expected) {
assertEquals(expected, new UserService().hasAdminAccess(user));
}
}
26.3 行为验证
验证多态调用的正确性:
java复制interface Logger {
void log(String message);
}
class UserService {
private final Logger logger;
UserService(Logger logger) { this.logger = logger; }
void deleteUser(String id) {
logger.log("Deleting user " + id);
// 实际删除逻辑
}
}
@Test
void testLogging() {
Logger mockLogger = mock(Logger.class);
UserService service = new UserService(mockLogger);
service.deleteUser("123");
verify(mockLogger).log("Deleting user 123");
}
27. 多态与Java泛型系统
27.1 泛型方法的多态
类型参数化的多态方法:
java复制class CollectionUtils {
static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
List<T> result = new ArrayList<>();
for (T item : list) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
}
}
// 使用
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> longNames = CollectionUtils.filter(
names,
s -> s.length() > 4
);
27.2 通配符与多态
使用通配符增强灵活性:
java复制class Processor {
void processList(List<? extends Number> numbers) {
for (Number n : numbers) {
System.out.println(n.doubleValue());
}
}
}
// 可以传入List<Integer>, List<Double>等
new Processor().processList(Arrays.asList(1, 2, 3));
27.3 桥接方法
泛型类型擦除与多态的桥梁:
java复制interface Comparable<T> {
int compareTo(T o);
}
class MyInt implements Comparable<MyInt> {
@Override
public int compareTo(MyInt o) { /*...*/ }
// 编译器生成的桥接方法
public int compareTo(Object o) {
return compareTo((MyInt) o);
}
}
28. 多态与Java异常处理
28.1 异常层次的多态
通过异常继承实现统一处理:
java复制interface DataAccess {
void save(Data data) throws DataAccessException;
}
class DatabaseAccess implements DataAccess {
@Override
public void save(Data data) throws DatabaseException {
// 可能抛出DatabaseException
}
}
// 使用
try {
dataAccess.save(data);
} catch (DataAccessException e) {
// 可以捕获所有子类异常
logger.error("Data access failed", e);
}
28.2 异常转换模式
将底层异常转换为业务异常:
java复制interface ExceptionTranslator {
BusinessException translate(Exception e);
}
class SqlExceptionTranslator implements ExceptionTranslator {
@Override
public BusinessException translate(Exception e) {
if (e instanceof SQLIntegrityConstraintViolationException) {
return new BusinessException("数据已存在");
}
return new BusinessException("数据库操作失败");
}
}
28.3 异常处理策略
可配置的异常处理:
java复制interface ExceptionHandler {
void handle(Exception e);
}
class LoggingHandler implements ExceptionHandler { /*...*/ }
class RetryHandler implements ExceptionHandler { /*...*/ }
class Processor {
private ExceptionHandler handler;
void setHandler(ExceptionHandler h) { handler = h; }
void process() {
try {
doProcess();
} catch (Exception e) {
handler.handle(e);
}
}
}
29. 多态在Java持久层框架中的应用
29.1 ORM映射策略
不同实体的不同映射策略:
java复制interface MappingStrategy<T> {
String mapToTable(T entity);
Map<String, Object> mapToColumns(T entity);
}
class AnnotationMappingStrategy implements MappingStrategy { /*...*/ }
class XmlMappingStrategy implements MappingStrategy { /*...*/ }
29.2 懒加载实现
通过代理实现懒加载:
java复制interface User {
String getName();
List<Order> getOrders();
}
class UserProxy implements User {
private User realUser;
private List<Order> orders;
@Override
public List<Order> getOrders() {
if (orders == null) {
orders = loadOrders();
}
return orders;
}
}
29.3 缓存策略
多级缓存的多态实现:
java复制interface CacheProvider {
void put(String key, Object value);
Object get(String key);
