Java:更快的重载或if / else

时间:2009-04-16 21:54:53

标签: java optimization polymorphism conditional overloading

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

我将获得一个值,可以是long,int,string等,我必须分别创建一个LongObject,IntObject,StringObject等。

如下所示重载方法会更快(a)或只使用elseif,如下所示(b)?

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

我也可以听到你们中的一些人说要测试一下。当然,我应该。我还想知道如果有人知道这种类型的重载是如何处理的。

请让我知道你的想法。

谢谢, JBU

A)

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某种甚至使用重载方法。

7 个答案:

答案 0 :(得分:21)

这里有一个巨大的差异:在编译时选择重载,而你的“if(值很长)”将是执行时测试。< / p>

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

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

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

以下是一个例子:

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)被调用。

答案 1 :(得分:5)

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

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

BaseObject getObject(String s)
{
     return new StringObject(s);
}

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

答案 2 :(得分:1)

不要担心,除非条件每秒测试数百万次并不重要。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

这通常被称为“早期结合”与“晚期结合”。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

最重要的是,getObj(int),getObj(string)等 - 如果你尝试传递一些不期望的东西,它将在编译时失败。

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