Java 匹配函数名但参数不同

Java 匹配函数名但参数不同,java,function,syntax,permutation,Java,Function,Syntax,Permutation,在学习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++){ Str

在学习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));
    }
  }
}

我得到第一个置换函数接受一个字符串并调用第二个置换函数,它完成了所有的工作。然而,第二个置换不是对第一个置换函数的重新说明吗?Java如何识别和使用第一个置换函数而不覆盖它?

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

这意味着第二个方法在第一个方法执行前已加载/准备就绪,而第一个方法在第二个方法执行前已加载/准备就绪

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

此外,该方法是重载的

在java中,如果参数不同,可以在同一个类中创建多个同名方法。这些方法将被视为不同的方法,这是传递给该方法的参数的结尾

换句话说,名称本身并不定义调用哪个方法,而是定义签名,包括返回值以外的参数。java将如何识别和使用第一个置换函数

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


正如其他人所说,这是一种方法重载

与Python不同,在Java中,这两个声明是并行的,第二个声明并不取代第一个声明。在Java中,规则大致是,当您调用具有多个定义的方法(也称为重载方法)时,Java将查找与您调用的参数最匹配的方法并运行该方法。所以permutationhi调用第一个版本,permutationhi调用第二个版本

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


这样做的结果是,Java还可以在编译时检查方法的每个重载版本是否都可以调用:例如,如果您编写了两个置换版本,它们都只以一个字符串作为参数,那么编译器会给您一个错误,并且根本不会编译您的程序。在python中,您只需要得到第二个定义。

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

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

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

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

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方法栏。。。福班的。请注意,注释不负责行为,只负责编译时检查,以确保至少在一个父类中存在void barString baz方法

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

更奇怪的是,如果方法被重载,那么要调用的方法的签名将在编译时生成。这意味着只能考虑静态类型的参数。让我们看看下面的代码,并找出结果:

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");
    }
}

现在什么是静态类型的s?它是左边的类型,其中声明了s,因此调用了printfinal字符串s,并使用字符串参数进行了调用。o的静态类型是什么?同样,它是左边的类型,其中o是declard,因此调用printfail对象o,并使用对象参数进行调用,然后打印出来。有人可能会说,在这个简单的例子中,编译器可能会发现o的类型只能是字符串,但基于编译器在编译时识别类型的能力,这种行为只会让人更加困惑。

这可能就是所谓的方法重载吗?这就是所谓的重载。该方法是通过其签名定义的。签名由函数名以及按顺序排列的参数类型组成。返回类型不是方法签名的一部分。方法签名的详细信息在中定义。它不会覆盖它。这被称为这是重载,Python不支持它不能在其中的重载
任何有用的方法,因为Python不是静态类型语言。在Python中,函数是一级对象,当您调用函数时,它将解析为您实际使用的名称或引用是什么函数对象。在Java中,编译器根据名称和signatureNote(一个重要的区别)来确定要调用哪个实际方法,Python没有变量/函数声明。重要提示:决定是在静态类型上完成的,而不是实际参数的动态类型。这如何回答这个问题?