这是动态调度吗?
这是动态调度:
abstract class A{
public method Meth1(){
//somecode
}
}
class B extends A{
}
class C extends A{
}
完全在另一个类中吗:
Some_Method(A a){
a.Meth1();
}
我不确定这是否是动态调度,因为两个子类的行为相同?
如果不是,如果行为是根据子类定义的,那么它是否是动态分派?
Is this dynamic dispatch:
abstract class A{
public method Meth1(){
//somecode
}
}
class B extends A{
}
class C extends A{
}
In another class entirely:
Some_Method(A a){
a.Meth1();
}
I'm not sure if this is dynamic dispatch because the behaviour is the same on both subclasses?
If it's not, would it be dynamic dispatch if the behaviour was defined per the subclasses?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我不确定您所说的具体问题(如果静态地知道调用的方法仅在一个类中声明,则可能存在一些特定于实现的优化,它将绕过运行时类型检查),但实际上,动态分派允许
Meth1
方法的实际实现在运行时确定。因此,即使现在B
和C
都不会覆盖Meth1
,稍后,如果覆盖,动态调度将确保如果运行时类型为形式参数a
是B
,那么实际的实现是在B
上。C
的情况也是如此。将此与 Java 中的方法重载进行对比,其中实际方法是在编译时根据所使用参数的声明类型确定的。
I'm not sure what you say about you're specific question (there might be some implementation specific optimization that will bypass runtime type checking if the invoked method is statically known to be declared in just one class), but indeed, dynamic dispatch allows the actual implementation of the
Meth1
method to be determined at runtime. So, even if right now, neitherB
norC
overrideMeth1
, later, if overriden, dynamic dispatch will ensure that if the runtime type of the formal parama
isB
, then the actual implementation will be that onB
. Similarly in the case ofC
.Contrast this with method overloading in Java where the actual method is determined at compilation time based on the declared type of used arguments.
它是动态分派,因为编译器在为调用类生成字节码时不能假设它知道类的全部内容。
字节码解释器或 JIT 编译器在运行时也不会,至少因为类可以动态加载。
在我看来,这使得java除了使用动态调度之外别无选择,而不是“走捷径”,即优化对基类调用的调用。
It is dynamic dispatch because the compiler cannot assume, when producing bytecode for the calling class, that it knows the full universe of classes.
Neither will the bytecode interpreter or the JIT compiler at runtime, at least because classes could be loaded dynamically.
In my view, this leaves java no other option than use dynamic dispatch, and not 'cut corners' i.e. optimise calls into base class calls.
是的!。
因为在Java中所有实例方法默认都是虚拟的。
(你能用 Java 编写虚拟函数/方法吗?)
然后解析 a.Meth1() 需要在运行时完成。
请记住,您可以使用从 A 派生并覆盖该方法的类来动态加载新的 JAR。
Yes, it is!.
Because in Java all instance methods are virtual by default.
(Can you write virtual functions / methods in Java?)
Then resolve a.Meth1() needs to be done in runtime.
Remember that you can load a new JAR dynamically with a class that derives from A having an override of that method.
动态调度是指根据实际类型而不是声明的类型选择方法实现。 Java 不支持动态调度,除非通过反射。这是静态类型的多态调度。
如果加载了单个实现,JVM 将应用单态优化(产生非常快的调用),当 JVM 看到传递给相同代码的第二个实现时,该优化将被撤消。
您可能听说过新的“invokedynamic”字节码,它在 JVM 中实现动态调度,但它旨在供其他 JVM 语言使用,Java 程序除了生成字节码之外不会使用它。
[编辑] 这是一个简单的例子:
Dynamic dispatch is when a method implementation is picked based on the actual and not the declared type. Java does not support dynamic dispatch, except through reflection. This is statically typed polymorphic dispatch.
If you have a single implementation loaded, the JVM will apply momomorphic optimization (yielding very fast calls) which will be undone when the JVM sees a second implementation passed to the same code.
You might have heard about the new 'invokedynamic' bytecode, which implements dynamic dispatch in the JVM, but it is intended to be used by other JVM languages and Java programs will not use it except when doing bytecode generation.
[Edit] Here is a simple example: