Overloading in Java and multiple dispatch(Java中的重载和多分派)
问题描述
我有一个集合(或列表或数组列表),我想在其中放置字符串值和双精度值.我决定让它成为一个对象的集合并使用重载和多态性,但是我做错了.
I have a collection (or list or array list) in which I want to put both String values and double values. I decided to make it a collection of objects and using overloading ond polymorphism, but I did something wrong.
我运行了一个小测试:
public class OOP {
void prova(Object o){
System.out.println("object");
}
void prova(Integer i){
System.out.println("integer");
}
void prova(String s){
System.out.println("string");
}
void test(){
Object o = new String(" ");
this.prova(o); // Prints 'object'!!! Why?!?!?
}
public static void main(String[] args) {
OOP oop = new OOP();
oop.test(); // Prints 'object'!!! Why?!?!?
}
}
在测试中,参数类型似乎是在编译时而不是在运行时决定的.这是为什么呢?
In the test seems like the argument type is decided at compile time and not at runtime. Why is that?
这个问题与:
多态性 vs 覆盖 vs 重载
尝试尽可能简单地描述多态性
好的,要调用的方法是在编译时决定的.是否有避免使用 instanceof
运算符的解决方法?
Ok the method to be called is decided at compile time. Is there a workaround to avoid using the instanceof
operator?
推荐答案
这篇文章秒了voo的答案,并提供了有关后期绑定/替代方案的详细信息.
This post seconds voo's answer, and gives details about/alternatives to late binding.
一般 JVM 只使用 single dispatch:运行时类型只考虑接收者对象;对于方法的参数,考虑静态类型.使用 方法表 (类似于 C++ 的虚拟表).您可以找到详细信息,例如在 HotSpot Wiki 中.
General JVMs only use single dispatch: the runtime type is only considered for the receiver object; for the method's parameters, the static type is considered. An efficient implementation with optimizations is quite easy using method tables (which are similar to C++'s virtual tables). You can find details e.g. in the HotSpot Wiki.
如果您希望参数多次调度,请查看
If you want multiple dispatch for your parameters, take a look at
- groovy.但据我所知,它有一个过时的、缓慢的多调度实现(参见例如 这个性能比较),例如没有缓存.
- clojure,但这与 Java 完全不同.
- MultiJava,它为 Java 提供了多重调度.此外,您可以使用
this.resend(...)
而不是super(...)
来调用封闭方法的最具体的重写方法;- 值调度(下面的代码示例).
- groovy. But to my latest knowledge, that has an outdated, slow multiple dispatch implementation (see e.g. this performance comparison), e.g. without caching.
- clojure, but that is quite different to Java.
- MultiJava, which offers multiple dispatch for Java. Additionally, you can use
this.resend(...)
instead ofsuper(...)
to invoke the most-specific overridden method of the enclosing method;- value dispatching (code example below).
如果你想坚持使用 Java,你可以
- 通过在更细粒度的类层次结构上移动重载方法来重新设计您的应用程序.Josh Bloch 的 Effective Java 项目中给出了一个示例41(明智地使用重载);
- 使用一些设计模式,例如策略、访问者、观察者.这些通常可以解决与多分派相同的问题(即,在那些情况下,对于使用多分派的那些模式,您有一些简单的解决方案).
- redesign your application by moving overloaded methods over a finer grained class hierarchy. An example is given in Josh Bloch's Effective Java, Item 41 (Use overloading judiciously);
- use some design patterns, such as Strategy, Visitor, Observer. These can often solve the same problems as multiple dispatch (i.e. in those situations you have trivial solutions for those patterns using multiple dispatch).
值调度:
class C { static final int INITIALIZED = 0; static final int RUNNING = 1; static final int STOPPED = 2; void m(int i) { // the default method } void m(int@@INITIALIZED i) { // handle the case when we're in the initialized `state' } void m(int@@RUNNING i) { // handle the case when we're in the running `state' } void m(int@@STOPPED i) { // handle the case when we're in the stopped `state' } }
这篇关于Java中的重载和多分派的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java中的重载和多分派
基础教程推荐
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01