6

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

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

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

这可能不是明显的性能差异。无论如何,重载方法可能以与 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 才能使用重载方法。

4

7 回答 7

24

这里有一个巨大的差异:重载是在编译时选择的,而你的“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)是因为编译时类型xis Object, not Stringx引用的对象的执行时类型String并不意味着foo(String)被调用。

于 2009-04-16T21:57:27.027 回答
6

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

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

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

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

于 2009-04-16T22:01:04.193 回答
1

不用担心,除非条件每秒测试数百万次,否则没关系。

于 2009-04-16T22:20:13.430 回答
0

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

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

于 2009-04-16T22:57:40.830 回答
0

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

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

于 2009-04-16T23:18:07.457 回答
0

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

于 2009-04-16T22:02:31.523 回答
0

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

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

于 2009-04-16T22:15:58.650 回答