Java匹配函数名称,但参数不同

问题描述 投票:0回答:1

我实际上来自python背景,我一直在研究Java中的“破解编码面试”。在第51页,我遇到了

void permutation(String str){
   permutation(str,"");
}
void permutation(String str, String prefix){
  if(str.length()==0){
    System.out.println(prefix);
  } else{
    for(int i=0;i<str.length();i++){
        String rem=str.substring(0,i)+str.substring(i+1);
         permutation(rem,prefix+str.charAt(i));
    }
  }
}

当尝试以Python的方式思考时,我有点困惑。我的要点是,第一个排列函数接受一个字符串,然后调用第二个排列函数来完成所有工作。但是,第二个排列不是在重新定义第一个排列函数吗? Java将如何识别和使用第一个排列函数?而不是覆盖它?

java python function syntax permutation
1个回答
2
投票

java如何识别和使用第一个排列函数?

当您调用该方法时,Java将看到您尝试传递给它的内容。根据您传递的参数,它将决定您尝试使用的方法的“版本”。

[就像其他人说的一样-这是方法重载


0
投票

[与Python不同,在Java中,这两个声明并存-第二个声明不能代替第一个。在Java中,规则大致是:当您调用具有多个定义的方法(又称“重载”方法)时,Java会查找与您调用的参数最匹配的方法并运行该方法。因此,permutation("hi")调用第一个版本,permutation("hi", "")调用第二个版本。

这里的根本区别在于,您可以想象在Python中解释器一次读取一个定义,并在每次获得新定义时替换其整体定义permutation。在Java中,您必须将其视为一次读取all permutation的定义,并为任何给定的调用调用最合适的定义。

((这样的结果是Java还在编译时检查方法的每个重载版本都是可调用的:例如,如果您编写了两个都仅以字符串作为参数的permutation版本,则编译器会给您一个错误,并且根本不会编译您的程序。在python中,您将获得第二个定义。)


0
投票

要解释语义是什么,我们需要看一下Java方法是如何区分的。

在Java中,方法由其签名标识。 JLS §8.4.2指定

如果两个方法具有相同的名称和参数类型,则它们具有相同的签名。

要注意的是,方法的返回类型是方法签名的not一部分。因此,如果有人会写:

public class Foo {
    void bar(String baz) {
    }

    String bar(String baz) {
    }
}

两个方法都具有相同的签名。在Java中,这将导致编译错误,因为不允许在同一类中使用两个具有相同签名的方法。

如果我们将继承权引入图片中,行为就会改变:

public class Foo {
    void bar(String baz);
}

public class Zoo extends Foo {
    @Override
    void bar(String baz);
}

在这种情况下,类别Zoo的类别overrides bar(...)方法Foo。请注意,注释不负责行为,仅负责编译时检查,以确保至少一个父类中存在方法void bar(String baz)

所提供的代码有两个名称相同但签名不同的方法。在Java中称为Overloading。因此,该方法被视为不相等。您可以重命名这些方法之一,它们不会或多或少地“相等”。

为了使事情变得更加奇怪,如果方法被重载,则在编译时为要调用的方法签名。这意味着只能考虑静态类型的参数。让我们看下面的代码,弄清楚结果是什么:

public class Test {
    public static void main(final String... args) {
        final String s = "foo";
        final Object o = s;
        print(s);
        print(o);
    }

    private static void print(final String s) {
        System.out.println("Called with String parameter");
    }

    private static void print(final Object o) {
        System.out.println("Called with Object parameter");
    }
}

Ideon demo

现在s的静态类型是什么?这是左侧的类型,其中声明了s,因此调用了print(final String s),并打印了"Called with String parameter"o的静态类型是什么?同样,它是左侧的类型,其中声明了o,因此调用了print(final Object o),并打印了"Called with Object parameter"。有人可能会争辩说,在这个琐碎的示例中,编译器可能会发现o的类型只能是String,但这种行为基于编译器在编译时识别类型的能力,只会使其更加混乱。


-1
投票

在Java中,整个类在执行方法之前已加载。

这意味着在执行第一种方法之前已加载/准备好第二种方法,而在执行第二种方法之前已加载/准备好了第一种方法。>>

这允许递归调用方法,并调用稍后将声明的方法。

此外,方法是重载

在Java中,如果参数不同,则可以在同一类中创建多个具有相同名称的方法。这些方法将被视为不同的方法,它们将传递给该方法的参数脱离顺序。

换句话说,名称本身并没有定义调用哪个方法,而是签名

,包括参数(不是返回值)
© www.soinside.com 2019 - 2024. All rights reserved.