gpt4 book ai didi

java - java接口(interface)中的泛型方法如何将 super 对象转换为具体的子类对象?

转载 作者:行者123 更新时间:2023-11-30 02:39:05 25 4
gpt4 key购买 nike

我有以下代码片段,它工作正常。

public class Test {
public static void main(String[] args) {
App app = new App();
app.setHandler(Apple.class, new AppleHandler());
app.setHandler(Banana.class, new BananaHandler());

app.process(new Apple());
app.process(new Banana());
}
}

class Fruit {}
class Apple extends Fruit {}
class Banana extends Fruit {}

interface Handler<T extends Fruit> {
public void handle(T fruit);
}

class AppleHandler implements Handler<Apple> {
@Override
public void handle(final Apple fruit) {
System.out.println("This is an apple.");
}
}

class BananaHandler implements Handler<Banana> {
@Override
public void handle(final Banana fruit) {
System.out.println("This is a banana.");
}
}

class App {
Map<Class, Handler> handlerMap = new HashMap<>();

public void setHandler(Class clazz, Handler handler) {
handlerMap.put(clazz, handler);
}

public void process(Fruit fruit) {
Handler handler = handlerMap.get(fruit.getClass());
handler.handle(fruit);// HERE, how java convert Fruit object to concrete subclass object automatically?
}
}

我希望 App 类以不同的方式处理不同的 Fruit,因此我定义 AppleHandler 来处理 AppleBananaHandler 来处理 BananaAppleHandlerBananaHandler 都实现了一个通用接口(interface) Handler,它具有一个通用方法 handlehandle 方法在 App.process 方法中被赋予一个 Fruit 对象,具体的 handle 方法将按预期被调用。看来,当调用具体的handle方法时,java会自动将Fruit对象转换为其真实类型。 java是如何实现这一点的?

最佳答案

It seems that java casts a Fruit object to its real type automatically when invoke concrete handle method. How does java achieve this?

这是正确的。编译器根据泛型参数插入强制转换。在您的代码中很难看到这一点,因为您使用了如此多的原始类型。

当你这样做时:

Handler handler = handlerMap.get(fruit.getClass());
handler.handle(fruit);

handler 的泛型参数未知,因此 fruit 被传递给 handle 方法的删除形式,看起来像:

public void handle(Fruit fruit)

所以代码可以编译。但此时,动态调度会调用 handle 的重写实现,例如您在 AppleHandler 中定义的实现:

@Override
public void handle(final Apple fruit) {
System.out.println("This is an apple.");
}

此时通用参数已知,并且参数被转换为Apple

这种转换也可以在 AppleHandler 类的字节码中看到:

 public void handle(test.Fruit);
Code:
0: aload_0
1: aload_1
2: checkcast #35 // class test/Apple
5: invokevirtual #37 // Method handle:(Ltest/Apple;)V
8: return

关于java - java接口(interface)中的泛型方法如何将 super 对象转换为具体的子类对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42299871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com