1. 多态的本质与Java实现机制
多态(Polymorphism)是面向对象编程的三大特性之一,它允许不同类的对象对同一消息做出响应。在Java中,多态的实现主要依赖于继承和方法重写机制。当父类引用指向子类对象时,调用的方法会根据实际对象类型动态绑定,这就是运行时多态的核心表现。
1.1 多态的类型体系
Java中的多态主要分为两种形式:
- 编译时多态:通过方法重载实现,根据参数列表在编译期确定调用哪个方法
- 运行时多态:通过方法重写实现,在运行期根据对象实际类型决定方法调用
java复制class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // 父类引用指向子类对象
myAnimal.makeSound(); // 输出"Bark",体现运行时多态
}
}
1.2 JVM层面的实现原理
在JVM中,方法调用分为解析调用和分派调用两种:
- 解析调用:在类加载的解析阶段就能确定唯一调用版本(如静态方法、私有方法等)
- 分派调用:包括静态分派(方法重载)和动态分派(方法重写)
动态分派通过方法表(Method Table)实现。每个类在方法区维护一个方法表,其中记录了实际可调用的方法入口地址。当发生方法调用时,JVM会:
- 查找对象的实际类型
- 在该类型的方法表中查找方法
- 如果找不到则向父类追溯
提示:使用
javap -c命令可以查看字节码中的invokevirtual指令,这是实现动态分派的关键
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 多态在Java设计模式中的应用
2.1 策略模式中的多态实现
策略模式通过定义算法族并封装每个算法,使它们可以互相替换。多态在这里使得算法可以独立于使用它的客户端变化。
java复制interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " via Credit Card");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " via PayPal");
}
}
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
2.2 工厂模式中的多态应用
工厂模式利用多态特性,将对象创建逻辑封装起来,客户端只需关心接口而不需要知道具体实现类。
java复制interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("Drawing Circle");
}
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Drawing Rectangle");
}
}
class ShapeFactory {
public Shape getShape(String shapeType) {
if(shapeType == null) return null;
if(shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
3. 多态使用中的常见问题与解决方案
3.1 类型转换异常(ClassCastException)
当向下转型不当时,会抛出ClassCastException。安全的做法是使用instanceof进行类型检查:
java复制Animal animal = new Dog();
if(animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
3.2 方法重写与隐藏的区别
- 方法重写:子类重写父类实例方法,运行时根据实际对象类型调用
- 方法隐藏:子类定义与父类相同的静态方法,编译时根据引用类型决定调用
java复制class Parent {
static void staticMethod() {
System.out.println("Parent static");
}
void instanceMethod() {
System.out.println("Parent instance");
}
}
class Child extends Parent {
static void staticMethod() { // 方法隐藏
System.out.println("Child static");
}
@Override
void instanceMethod() { // 方法重写
System.out.println("Child instance");
}
}
3.3 多态与字段访问
字段访问不具多态性,始终由引用类型决定:
java复制class Parent {
String field = "Parent field";
}
class Child extends Parent {
String field = "Child field";
}
public class Test {
public static void main(String[] args) {
Parent obj = new Child();
System.out.println(obj.field); // 输出"Parent field"
}
}
4. 多态性能优化实践
4.1 虚方法表优化
JVM为每个类维护虚方法表(vtable),包含该类所有可被重写的方法指针。方法调用时通过偏移量直接定位,避免每次搜索。
优化建议:
- 避免过深的继承层次(建议不超过3层)
- 减少不必要的方法重写
- 对性能关键方法考虑使用
final修饰
4.2 内联缓存技术
JIT编译器使用内联缓存优化虚方法调用:
- 单态内联缓存:记录最近一次调用的具体类型
- 多态内联缓存:记录少量常见类型
- 超多态内联缓存:退化为普通虚方法调用
注意:频繁的类型变化会导致内联缓存失效,影响性能。保持调用对象的类型稳定性有助于优化
4.3 接口与抽象类的选择
接口和抽象类都能实现多态,但各有特点:
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 多继承 | 支持(一个类可实现多个接口) | 不支持(单继承) |
| 方法实现 | Java 8+支持默认方法 | 可以有具体方法实现 |
| 字段 | 只能是常量(public static final) | 可以有实例字段 |
| 构造方法 | 无 | 可以有 |
| 设计目的 | 定义行为契约 | 代码复用和扩展 |
选择建议:
- 需要定义行为契约时用接口
- 需要代码复用时用抽象类
- 考虑未来扩展性,优先使用接口
5. 多态在Java集合框架中的应用
5.1 List接口的多态实现
java复制List<String> arrayList = new ArrayList<>(); // 基于数组的实现
List<String> linkedList = new LinkedList<>(); // 基于链表的实现
// 同样的List接口,不同的行为特征
arrayList.get(0); // O(1)时间复杂度
linkedList.get(0); // O(n)时间复杂度
5.2 Comparator与多态排序
通过Comparator接口可以实现不同的排序策略:
java复制class Employee {
String name;
int salary;
}
List<Employee> employees = ...;
// 按姓名排序
employees.sort(Comparator.comparing(e -> e.name));
// 按薪资排序
employees.sort(Comparator.comparingInt(e -> e.salary));
// 自定义复合排序
employees.sort(Comparator
.comparingInt((Employee e) -> e.salary)
.thenComparing(e -> e.name));
5.3 Java 8函数式接口与多态
Java 8引入的函数式接口(如Function、Predicate等)极大地扩展了多态的应用场景:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 不同的函数式实现
names.replaceAll(String::toUpperCase); // 方法引用
names.removeIf(s -> s.length() > 4); // Lambda表达式
// 组合函数
Function<String, Integer> lengthMapper = String::length;
Function<Integer, Integer> square = x -> x * x;
names.stream()
.map(lengthMapper.andThen(square))
.forEach(System.out::println);
6. 多态与Java异常处理
6.1 异常体系中的多态
Java异常处理充分利用了多态特性,所有异常都是Throwable的子类:
java复制try {
// 可能抛出各种异常的操作
} catch (IOException e) {
// 处理IO异常
} catch (Exception e) {
// 处理其他所有异常(多态捕获)
}
6.2 自定义异常中的多态实践
java复制class BusinessException extends RuntimeException {
BusinessException(String message) {
super(message);
}
}
class ValidationException extends BusinessException {
ValidationException(String field) {
super("Validation failed for field: " + field);
}
}
// 使用示例
try {
validateInput(input);
} catch (BusinessException e) {
// 可以捕获所有BusinessException及其子类
logger.error("Business error: " + e.getMessage());
}
7. 多态在Java反射API中的应用
7.1 通过反射实现动态方法调用
java复制class MyClass {
public void print(String message) {
System.out.println(message);
}
}
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getMethod("print", String.class);
method.invoke(obj, "Hello Reflection!"); // 动态调用
}
}
7.2 反射与多态的结合应用
java复制interface Service {
void execute();
}
class ServiceA implements Service {
public void execute() {
System.out.println("ServiceA executed");
}
}
class ServiceB implements Service {
public void execute() {
System.out.println("ServiceB executed");
}
}
class ServiceFactory {
static Service createService(String className) throws Exception {
Class<?> clazz = Class.forName(className);
return (Service) clazz.getDeclaredConstructor().newInstance();
}
}
8. Java多态高级特性
8.1 协变返回类型
Java 5开始支持协变返回类型,允许子类重写方法时返回更具体的类型:
java复制class Fruit {}
class Apple extends Fruit {}
class FruitProducer {
Fruit produce() {
return new Fruit();
}
}
class AppleProducer extends FruitProducer {
@Override
Apple produce() { // 返回类型是Fruit的子类
return new Apple();
}
}
8.2 桥接方法与多态
编译器在处理泛型类型擦除和协变返回类型时会生成桥接方法:
java复制class Node<T> {
T data;
void setData(T data) {
this.data = data;
}
}
class MyNode extends Node<Integer> {
void setData(Integer data) { // 重写父类方法
super.setData(data);
}
}
编译后,编译器会生成一个桥接方法:
java复制void setData(Object data) {
setData((Integer) data); // 桥接方法
}
8.3 多态与Java模块系统
Java 9引入的模块系统也利用了多态特性。服务接口定义在模块中,具体实现在其他模块提供:
java复制// module-info.java (服务提供模块)
module service.provider {
provides com.example.Service with com.example.ServiceImpl;
}
// module-info.java (服务消费模块)
module service.consumer {
uses com.example.Service;
}
// 使用ServiceLoader加载服务
ServiceLoader<Service> loader = ServiceLoader.load(Service.class);
for (Service service : loader) {
service.execute(); // 多态调用
}
9. 多态在Java新特性中的应用
9.1 记录类型(Record)与多态
Java 14引入的记录类型也支持多态:
java复制record Point(int x, int y) {}
record NamedPoint(String name, int x, int y) extends Point(x, y) {}
Point p = new NamedPoint("Origin", 0, 0);
System.out.println(p.x()); // 多态访问
9.2 模式匹配与多态
Java 16引入的模式匹配instanceof进一步简化了多态代码:
java复制Object obj = ...;
// 传统写法
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// 模式匹配写法
if (obj instanceof String s) {
System.out.println(s.length());
}
9.3 密封类(Sealed Class)与受控多态
Java 17引入密封类,可以精确控制哪些类可以继承父类:
java复制sealed interface Shape permits Circle, Rectangle, Triangle {
double area();
}
final class Circle implements Shape {
private final double radius;
Circle(double radius) { this.radius = radius; }
@Override
public double area() {
return Math.PI * radius * radius;
}
}
non-sealed class Rectangle implements Shape {
private final double width, height;
Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
}
10. 多态设计的最佳实践
10.1 里氏替换原则(LSP)
子类应该能够替换父类而不影响程序正确性:
- 子类方法的前置条件不能强于父类
- 子类方法的后置条件不能弱于父类
- 子类不应该抛出父类未声明的异常
- 子类应该保持父类的行为约定
10.2 依赖倒置原则(DIP)
高层模块不应该依赖低层模块,二者都应该依赖抽象:
- 使用接口或抽象类定义抽象层
- 具体实现依赖抽象而非相反
- 通过依赖注入实现解耦
10.3 组合优于继承
在以下情况考虑使用组合而非继承:
- 需要复用代码但不符合"is-a"关系
- 需要动态切换行为
- 避免过深的继承层次
java复制// 使用组合实现策略模式
class PaymentProcessor {
private PaymentStrategy strategy;
void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
void processPayment(int amount) {
strategy.pay(amount);
}
}
10.4 防御性编程技巧
- 对可能为null的对象引用进行检查
- 使用
@Override注解明确表明重写意图 - 对关键方法添加
final修饰防止意外重写 - 文档化可重写方法的契约和行为预期
11. 多态在Java框架中的典型应用
11.1 Spring框架中的多态
Spring的核心IoC容器大量使用多态:
java复制interface UserRepository {
User findById(Long id);
}
@Repository
class JpaUserRepository implements UserRepository {
public User findById(Long id) {
// JPA实现
}
}
@Repository
class JdbcUserRepository implements UserRepository {
public User findById(Long id) {
// JDBC实现
}
}
@Service
class UserService {
private final UserRepository repository;
@Autowired
public UserService(UserRepository repository) { // 依赖注入
this.repository = repository;
}
public User getUser(Long id) {
return repository.findById(id); // 多态调用
}
}
11.2 Hibernate/JPA中的多态映射
实体继承策略实现多态查询:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE):单表策略@Inheritance(strategy = InheritanceType.JOINED):连接表策略@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS):每个类单独表
java复制@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "payment_type")
class Payment {
@Id Long id;
BigDecimal amount;
}
@Entity
@DiscriminatorValue("CREDIT")
class CreditCardPayment extends Payment {
String cardNumber;
}
@Entity
@DiscriminatorValue("PAYPAL")
class PayPalPayment extends Payment {
String email;
}
11.3 Java Stream API中的多态
Stream操作通过多态支持各种数据源:
java复制// 不同数据源的Stream创建
Stream<String> listStream = List.of("a", "b", "c").stream();
Stream<String> setStream = Set.of("x", "y", "z").stream();
Stream<String> arrayStream = Arrays.stream(new String[]{"1", "2"});
// 多态的中间操作
Stream<String> filtered = listStream.filter(s -> s.length() > 1);
Stream<Integer> mapped = listStream.map(String::length);
Stream<String> sorted = listStream.sorted();
12. 多态与Java并发编程
12.1 多态的任务执行
通过Runnable和Callable接口实现多态的任务提交:
java复制ExecutorService executor = Executors.newFixedThreadPool(2);
// 多态的Runnable实现
executor.execute(() -> System.out.println("Task 1"));
// 多态的Callable实现
Future<Integer> future = executor.submit(() -> {
TimeUnit.SECONDS.sleep(1);
return 42;
});
12.2 多态的锁实现
Java并发包提供了多种Lock实现:
java复制Lock reentrantLock = new ReentrantLock();
Lock readLock = new ReentrantReadWriteLock().readLock();
Lock writeLock = new ReentrantReadWriteLock().writeLock();
// 统一Lock接口,不同实现
void doWithLock(Lock lock) {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
12.3 多态的并发集合
Java提供了一系列线程安全的集合实现:
java复制List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
List<String> copyOnWriteList = new CopyOnWriteArrayList<>();
Map<String, String> concurrentMap = new ConcurrentHashMap<>();
Queue<String> blockingQueue = new LinkedBlockingQueue<>();
13. 多态与Java函数式编程
13.1 函数式接口的多态应用
Java 8的函数式接口为多态提供了更灵活的实现方式:
java复制@FunctionalInterface
interface StringProcessor {
String process(String input);
default StringProcessor andThen(StringProcessor after) {
return input -> after.process(this.process(input));
}
}
class ProcessorDemo {
static void processString(String input, StringProcessor processor) {
System.out.println(processor.process(input));
}
public static void main(String[] args) {
StringProcessor toUpper = String::toUpperCase;
StringProcessor reverse = s -> new StringBuilder(s).reverse().toString();
processString("hello", toUpper); // 输出"HELLO"
processString("world", reverse); // 输出"dlrow"
processString("java", toUpper.andThen(reverse)); // 输出"AVAJ"
}
}
13.2 Lambda表达式与多态
Lambda表达式是多态的一种简洁实现方式:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 不同的Comparator实现
names.sort((a, b) -> a.compareTo(b)); // 自然排序
names.sort((a, b) -> b.compareTo(a)); // 逆序
names.sort(Comparator.comparingInt(String::length)); // 按长度排序
13.3 方法引用与多态
方法引用是多态的另一种表现形式:
java复制class Formatter {
static String format(String input) {
return "[" + input + "]";
}
String instanceFormat(String input) {
return "{" + input + "}";
}
}
List<String> strings = Arrays.asList("a", "b", "c");
// 静态方法引用
strings.stream().map(Formatter::format).forEach(System.out::println);
// 实例方法引用
Formatter formatter = new Formatter();
strings.stream().map(formatter::instanceFormat).forEach(System.out::println);
// 构造方法引用
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> newList = listSupplier.get();
14. 多态与Java注解处理
14.1 注解处理器中的多态
注解处理器通过多态支持不同的处理策略:
java复制@SupportedAnnotationTypes("com.example.MyAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class MyAnnotationProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
for (Element element : elements) {
// 处理被注解的元素
}
}
return true;
}
}
14.2 自定义注解与多态
通过注解实现多态行为:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface ProcessorType {
String value();
}
@ProcessorType("csv")
class CsvProcessor implements DataProcessor {
public void process(Data data) {
// CSV处理逻辑
}
}
@ProcessorType("json")
class JsonProcessor implements DataProcessor {
public void process(Data data) {
// JSON处理逻辑
}
}
class ProcessorFactory {
static DataProcessor createProcessor(Class<?> processorClass) {
ProcessorType annotation = processorClass.getAnnotation(ProcessorType.class);
if (annotation != null) {
// 根据注解值创建处理器
}
throw new IllegalArgumentException("Invalid processor class");
}
}
15. 多态在Java测试中的应用
15.1 测试桩(Stub)与多态
利用多态创建测试桩:
java复制interface UserService {
User getUser(Long id);
}
class RealUserService implements UserService {
public User getUser(Long id) {
// 实际数据库查询
}
}
class StubUserService implements UserService {
public User getUser(Long id) {
return new User(id, "Test User");
}
}
class UserControllerTest {
@Test
void testGetUser() {
UserService stubService = new StubUserService();
UserController controller = new UserController(stubService);
User user = controller.getUser(1L);
assertEquals("Test User", user.getName());
}
}
15.2 Mock框架中的多态
Mock框架如Mockito利用多态创建模拟对象:
java复制@Test
void testOrderProcessing() {
PaymentService mockPayment = mock(PaymentService.class);
when(mockPayment.process(anyDouble())).thenReturn(true);
OrderProcessor processor = new OrderProcessor(mockPayment);
boolean result = processor.processOrder(new Order(100.0));
assertTrue(result);
verify(mockPayment).process(100.0);
}
15.3 参数化测试与多态
JUnit 5参数化测试支持多态数据源:
java复制@ParameterizedTest
@ValueSource(strings = {"racecar", "radar", "madam"})
void testPalindrome(String candidate) {
assertTrue(StringUtils.isPalindrome(candidate));
}
@ParameterizedTest
@MethodSource("provideTestData")
void testWithMethodSource(User user, boolean expected) {
assertEquals(expected, user.isAdmin());
}
private static Stream<Arguments> provideTestData() {
return Stream.of(
Arguments.of(new User("admin", true), true),
Arguments.of(new User("user", false), false)
);
}
16. 多态与Java序列化
16.1 多态对象的序列化
Java序列化机制支持多态对象图:
java复制class Animal implements Serializable {
String name;
}
class Dog extends Animal {
String breed;
}
public class SerializationDemo {
public static void main(String[] args) throws Exception {
Animal animal = new Dog();
animal.name = "Buddy";
((Dog) animal).breed = "Golden Retriever";
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("animal.ser"))) {
oos.writeObject(animal);
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("animal.ser"))) {
Animal deserialized = (Animal) ois.readObject();
System.out.println(deserialized.getClass()); // 输出Dog
}
}
}
16.2 自定义序列化与多态
通过writeObject和readObject方法实现自定义序列化逻辑:
java复制class Employee implements Serializable {
String name;
transient Department department; // 不自动序列化
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(department.getName()); // 自定义序列化部门
}
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
String deptName = (String) ois.readObject();
this.department = Department.getByName(deptName); // 自定义反序列化
}
}
17. 多态与Java本地方法接口(JNI)
17.1 通过JNI实现多态回调
Java代码:
java复制class NativeCallback {
static {
System.loadLibrary("native");
}
public native void registerCallback(Callback callback);
public static void main(String[] args) {
NativeCallback nativeCallback = new NativeCallback();
nativeCallback.registerCallback(new Callback() {
public void invoke(String message) {
System.out.println("Java callback: " + message);
}
});
}
}
interface Callback {
void invoke(String message);
}
C++代码:
cpp复制JNIEXPORT void JNICALL Java_NativeCallback_registerCallback
(JNIEnv *env, jobject obj, jobject callback) {
jclass callbackClass = env->GetObjectClass(callback);
jmethodID invokeMethod = env->GetMethodID(callbackClass, "invoke", "(Ljava/lang/String;)V");
// 调用Java回调
jstring message = env->NewStringUTF("Hello from native");
env->CallVoidMethod(callback, invokeMethod, message);
}
18. 多态与Java安全管理
18.1 多态权限检查
Java安全管理器通过多态实现灵活的权限控制:
java复制class SecurityManager {
void checkPermission(Permission perm) {
// 默认实现
}
}
class CustomSecurityManager extends SecurityManager {
@Override
void checkPermission(Permission perm) {
if (perm instanceof FilePermission) {
// 自定义文件权限检查
} else if (perm instanceof SocketPermission) {
// 自定义套接字权限检查
}
super.checkPermission(perm);
}
}
18.2 策略文件中的多态
Java安全策略文件支持多态权限分配:
code复制grant codeBase "file:/path/to/application.jar" {
permission java.io.FilePermission "/tmp/-", "read,write";
permission java.net.SocketPermission "*.example.com:80", "connect";
};
19. 多态与Java国际化
19.1 多态的资源包加载
Java资源包加载机制利用多态支持不同的资源来源:
java复制// 类路径资源
ResourceBundle bundle1 = ResourceBundle.getBundle("Messages");
// 属性文件资源
ResourceBundle bundle2 = ResourceBundle.getBundle(
"com.example.Messages",
new Locale("zh", "CN"));
// 自定义资源包控制
ResourceBundle bundle3 = ResourceBundle.getBundle(
"Messages",
Locale.getDefault(),
new ResourceBundle.Control() {
@Override
public List<String> getFormats(String baseName) {
return Arrays.asList("xml");
}
});
19.2 多态的消息格式化
MessageFormat类支持多态的参数格式化:
java复制String pattern = "At {0,time,short} on {0,date,long}, {1} occurred.";
MessageFormat fmt = new MessageFormat(pattern, Locale.US);
Object[] args = {new Date(), "a disk error"};
String result = fmt.format(args);
20. 多态与Java脚本引擎
20.1 多态脚本执行
通过ScriptEngine接口支持多种脚本语言:
java复制ScriptEngineManager manager = new ScriptEngineManager();
// JavaScript
ScriptEngine jsEngine = manager.getEngineByName("JavaScript");
jsEngine.eval("print('Hello from JavaScript')");
// Groovy
ScriptEngine groovyEngine = manager.getEngineByName("Groovy");
groovyEngine.eval("println 'Hello from Groovy'");
// Python (Jython)
ScriptEngine pythonEngine = manager.getEngineByName("python");
pythonEngine.eval("print 'Hello from Python'");
20.2 脚本与Java对象交互
脚本引擎通过多态实现与Java对象的双向交互:
java复制ScriptEngine engine = manager.getEngineByName("JavaScript");
// Java对象传递给脚本
engine.put("list", new ArrayList<String>());
engine.eval("list.add('JavaScript item')");
// 从脚本获取对象
List<?> result = (List<?>) engine.eval("Java.to([1, 2, 3], 'java.util.List')");
