有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java关于方法重写

对于下面的java代码段,“run”方法出现四次。我对这四次“跑”的关系感到相当困惑。原始代码相当长,我只保留了与我的问题相关的部分

   1. public final class Job extends AbstractJob {  
   2.   private Job( ) {  
   3.   }  
   4.   public static void main(String[] args) throws Exception {    
   5.            new Job( ).run(new Path("testdata"), output, 10 );  
   6.   }  
   7.   
   8.   @Override  
   9.   public int run(String[] args) throws IOException, ClassNotFoundException,      InterruptedException {  
  10.         run(input, output, alpha0);  
  11.         return 0;  
  12.   }    
  13.   public void run(Path input,  Path output,  double alpha0)  
  14.     throws IOException, ClassNotFoundException, InterruptedException {      
  15.     ClusterDriver.run(directoryInput, output, alpha0);      
  16.   }  
  17. }  

我可以如下理解这段代码的调用顺序吗

首先,调用第5行的run方法。由于其特殊的参数设置(3个参数),编译器会自动使用第13行中定义的run方法。(如果第5行中只有一个参数,那么编译器将使用第9行中定义的run方法

对于第9行中定义的run方法,它将在第10行调用run方法,这实际上是在第13行中定义的run方法

我的理解正确吗


共 (4) 个答案

  1. # 1 楼答案

    大多数事情你都做对了,但我想纠正的陈述很少:

    if we only have one parameter in line 5, then compiler will use the run method defined in line 9 instead.
    

    这并不完全正确,第9行的方法接受String[]类型的参数,您需要传递一个数组来调用此方法

    For the run method defined in line 9, it will call run method at line 10, which essentially is the run method defined at line 13.
    

    在第10行,您将看到语法错误,因为input, output, alpha0在该方法中未定义。您需要接受传递的String[] args参数并将其转换为input, output, alpha0参数,以调用run的其他实现

  2. # 2 楼答案

    只有最后一次运行方法定义才重要

    另一个run方法(采用String[])调用此方法,因此其行为类似于某种“代理”,而main方法中的另一个run调用可以选择调用这两种方法中的任何一种——“代理”run方法(采用String[] args)或最后一个run方法,这实际上是“跑步”

  3. # 3 楼答案

    是的,这是正确的,只是这是方法重载,而不是重写

    这个类在第9行和第13行定义了两个run方法,它们具有不同数量的参数。因此run方法是重载的。(重写发生在子类中重新定义虚拟基类方法的情况下-显然发生在第9行定义的方法上,正如其注释所证明的,但这在这个特定问题中不起作用。)

    还有两个对run的调用(在第5行和第10行),它们都解析为使用3个参数(在第13行定义)调用该方法

  4. # 4 楼答案

    你的基本分析是正确的

    (为了澄清其他人提出的观点:重载是指方法具有相同的名称但签名不同,而重写是指方法与超类中的方法具有相同的名称和参数类型)

    作为将来的参考,您应该知道,在重载方法的情况下,Java中的方法解析(名称+参数->;方法选择)实际上很难理解。使用的确切行为写在Java Language Spec (JLS), section 15.12中,并涉及一些一般微妙之处:

    • 重载方法解析是在编译时而不是运行时完成的。(根据最特定子类的方法,在运行时选择方法覆盖具有相同签名的。)如果编译器知道某个参数是Foo的实例(例如,它的类是FooFoo的子类),那么它将使用Foo作为参数的类,而不是它的“实”类

    • 确定使用哪种方法的问题包括:

      • 方法是否为varargs(将...作为最后一个参数,例如foo(Object a, String... b)
      • 方法的声明参数是原语还是包装原语,例如floatvsFloat
      • 一个方法的声明参数是否比另一个“更具体”(子类比它们的超类更具体)

    这很复杂,但你有基本的理解