Java:更快的重载或 if/else

Posted

技术标签:

【中文标题】Java:更快的重载或 if/else【英文标题】:Java: which is faster overloading or if/else 【发布时间】:2010-10-19 23:33:43 【问题描述】:

我有子类,每个子类与其他成员一起携带不同类型的值。可能有LongObject、IntObject、StringObject等。

会给我一个值,可以是long、int、string等,我要分别创建一个LongObject、IntObject、StringObject等。

像下面 (a) 所示重载方法会更快还是只使用下面 (b) 所示的 elseif 会更快?

这可能不是明显的性能差异。无论如何,重载方法可能以与 if/else 类似的方式实现。我不知道。

我也可以听到你们中的一些人说只是测试它。当然,我应该这样做。我也想知道这种类型的重载是如何在后台处理的,如果有人知道的话。

请告诉我你的想法。

谢谢, jbu

一)

BaseObject getObject(long l)

     return new LongObject(l);


BaseObject getObject(int i)

     return new IntObject(i);


BaseObject getObject(String s)

     return new StringObject(s);


...

b)

BaseObject getObject(Object x)

    if(value is a long)
         return new LongObject((Long)x);
    else if(value is an int)
         return new IntObject((Int)x);
    else if(value is a String)
         return new StringObject((String)x);
    ...

编辑:我想我并没有完全添加所有细节,你们中的一些人抓住了它。对于这两种选择,我仍然必须获取一个对象/值,并根据该值确定它是什么类型。因此,我仍然需要执行某种 if/else 操作才能使用重载方法。

【问题讨论】:

我对此类问题的个人哲学:时间吧!在每一个上运行几百万次迭代,看看哪一个需要更长的时间。 我就知道有人会这么说:) 只需创建一个测试并自己回答。 【参考方案1】:

这里有一个巨大的差异:重载是在编译时选择的,而您的“if (value is a long)”将是一个执行时测试。

如果您在编译时知道类型,我强烈建议您使用该信息。如果你不这样做,那么重载选项无论如何都不可行。

编辑:评论建议我详细说明在编译时选择的重载。

编译器根据参数的编译时间信息选择调用哪个方法签名。这与 覆盖 不同,其中要使用的方法实现由方法的实际目标的类型决定。

这是一个例子:

public class Test

    public static void main(String[] args)
    
        Object x = "I'm a string";
        foo(x);
    

    public static void foo(String x)
    
        System.out.println("foo(String)");
    

    public static void foo(Object x)
    
        System.out.println("foo(Object)");
    

这会打印出foo(Object),因为x 的编译时类型是Object,而不是Stringx 所引用的对象的执行时类型是String 并不意味着调用了foo(String)

【讨论】:

我不确定“在编译时选择重载”是什么意思。你能详细说明一下吗?我看到这些方法是在编译时编译的(...),但对这些方法的调用可能不是。我错过了什么吗? 哦,我明白了你的陈述背后的逻辑。你是说我需要一个 if/else 语句来决定使用哪个重载方法。如果我要获得一个未知类型的对象,我需要在使用重载方法之前对其进行 if/else 转换。对吗? @jbu:是的,我相信你现在明白了。 谢谢,它帮助我了解了幕后发生的事情。【参考方案2】:

重载解决方案更快(更好),因为它是在编译时解决的。

基本上,编译器会在您向其传递值时确定调用哪个方法。当你调用 getObject("abc") 时,编译器会发出对方法的调用:

BaseObject getObject(String s)

     return new StringObject(s);

而不是尝试通过您的 if ... else 状态并在运行时评估对象类型(这是一个缓慢的活动)。

【讨论】:

【参考方案3】:

不用担心,除非每秒测试数百万次,否则无关紧要。

【讨论】:

【参考方案4】:

a)(重载)会更快,因为它为即时编译器提供了优化的机会。它可以决定内联新对象的创建。

【讨论】:

【参考方案5】:

任何时候您必须在运行时评估类型信息,这可能是一个相对较慢的操作。当您有选择时,编写在编译时这样做的代码几乎总是更可取的。

这通常被称为“早期绑定”与“后期绑定”。

【讨论】:

【参考方案6】:

级联条件在 OO 编程中是不好的因果报应,在测试对象的类型时非常难看。该语言已经为测试之王提供了多态性。

另外,作为一个非 Java 人,我会使用 getLong(l)getInt(i)getString(s)。 我发现方法重载比没有更令人困惑(恕我直言,静态类型不应该影响程序执行(除了优化方面(尽管看起来我不是 Lisper :))))

【讨论】:

【参考方案7】:

最重要的是,getObj(int)、getObj(string) 等 - 如果您尝试传递未预期的内容,则会在编译时失败。

如果您允许将任何对象传递到方法中,您可能会有一个实例,其中应用程序试图传递该方法无法处理的东西,并且您最终会遇到一个丑陋的运行时错误。

【讨论】:

以上是关于Java:更快的重载或 if/else的主要内容,如果未能解决你的问题,请参考以下文章

JAVA方法重载

java - DAO 方法约定 - 重载或更改方法名称?

Java的重载和重写的区别

java 重载和重写的区别

Java 中方法的重载

java语言中,overload(重载)和override(覆盖)有何区别?