Java重载和多调度 [英] Overloading in Java and multiple dispatch

查看:72
本文介绍了Java重载和多调度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个集合(或列表或数组列表),我想在其中同时放置String值和double值.我决定使它成为对象的集合,并使用重载ond多态性,但是我做错了事.

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仅使用单调度:运行时间类型仅用于接收器对象;对于方法的参数,将考虑静态类型.使用方法表(类似于C ++的方法表),可以轻松高效地进行优化虚拟表).您可以找到详细信息,例如在热点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 of super(...) to invoke the most-specific overridden method of the enclosing method;
      • value dispatching (code example below).

      如果您要坚持使用Java ,则可以

      • 通过在更细粒度的类层次结构上移动重载方法来重新设计应用程序.在 Josh Bloch的有效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重载和多调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆