我有子课程,每个子课程与其他成员一起携带不同类型的值。可能有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某种甚至使用重载方法。
答案 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
,而不是String
。 x
引用的对象的执行时类型为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)等 - 如果你尝试传递一些不期望的东西,它将在编译时失败。
如果您允许将任何对象传递给该方法,您可能会有一个实例,其中该应用程序尝试传递该方法无法处理的内容,并且您最终会遇到一个难看的运行时错误。