Java中的方法签名是否包含其返回类型?


102

Java类/接口中的方法签名是否包含其返回类型?

例:

Java是否知道这两种方法之间的区别:

public class Foo {
    public int  myMethod(int param) {}
    public char myMethod(int param) {}
}

还是仅重要的方法名称和参数列表?


7
顺便说一句,在Java 6中处理泛型时存在一个错误,该错误使您可以同时使用这两种方法,因为JVM确实在签名中使用了返回类型并有选择地调用它们。此问题已在Java 7中修复。vanillajava.blogspot.co.uk
2011/

Answers:


146

Oracle Docs报价:

定义:方法声明的两个组成部分包括方法签名 -方法的名称和参数类型。

在此处输入图片说明

由于对问题进行了编辑以包括以下示例:

public class Foo {
    public int  myMethod(int param) {}
    public char myMethod(int param) {}
}

不,编译器不会知道它们之间的区别,因为它们的签名myMethod(int param)是相同的。第二行:

    public char myMethod(int param) {}

会给您带来错误:方法已经在class中定义,可以进一步确认上述声明。


因此,您的意思是我们不能在类中有两个方法具有相同的方法名称,相同的参数以及不同的返回类型?
Kasun Siyambalapitiya

6
我们不能的@KasunSiyambalapitiya。编译器如何知道在这种情况下要调用哪些方法foo.bar(baz);
Kolyunya

@Jops,如果我们有throws关键字怎么办?它也属于签名吗?
阿基拉(Akila Amarasinghe),

19

Java中的类方法签名是否包含返回类型?

在Java中不是,但是在此JVM中却可以,这可能导致明显的混乱。

Java中的接口方法签名是否包含返回类型?

与类方法相同。

还是只有方法名称和参数列表?

Java的方法名称和参数类型。例如,参数注释和名称无关紧要。


1
您的意思是“在Java中不是,但是在JVM中是”。您能否详细说明如何在JVM中使用?
塔伦·马甘蒂

3
@TarunMaganti JVM在方法签名中包括返回类型。Java作为一种语言不是。
彼得·劳瑞

3
@xyz这是您可以通过读取字节码而不是Java代码看到的东西。任何字节码都表明这一点。
彼得·劳瑞

8

在字节码级别,“返回类型”是方法签名的一部分。考虑一下

public class Test1  {
    public Test1 clone() throws CloneNotSupportedException {
        return (Test1) super.clone();
    }
}

在字节码中有2个clone()方法

public clone()LTest1; throws java/lang/CloneNotSupportedException 

public clone()Ljava/lang/Object; throws java/lang/CloneNotSupportedException 

它们仅在返回类型上有所不同。


1
这是一种误导,因为实例方法隐式地将实例作为第一个参数。曾经有人认为om(a)实际上是m(o,a)。因此,在克隆的情况下,区别在于参数不是返回类型。
惠勒


7

Java语言规范

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

因此,不,返回类型不是方法签名的一部分。


6

在JAVA和许多其他语言中,可以调用不带变量的方法来保存返回值。如果返回类型是方法签名的一部分,则在不指定保留返回值的变量的情况下,无法知道在调用时将调用哪个方法。


4

兄弟,在Java中,我们仅通过名称和参数来调用方法,而仅在代码中使用它们,例如

myMethod(20,40)

因此,JAVA只在其对应的声明(名称+参数)中搜索相似的内容匹配,这就是为什么方法签名仅包含方法的名称和参数的原因。:)



3

不,在Java中,方法签名不包括返回类型,但声明包括。

public             String         getString(String myString)

^access modifier   ^return type   ^name    ^parameter type and name

根据以下反馈进行了编辑:)


1
JLS并不是这样说的。它是“相同的名称和参数类型”。访问修饰符和参数名称也不是方法签名的一部分。
彼得·劳瑞

如果这是一个很好的测试问题,但是如果我正在编写程序,则不是在编写public getString(),而是在编写public String getString()
杰夫·霍桑

1
访问修饰符,返回类型和异常类型都没有签名,这就是为什么你不能拥有的一部分String method( String s ),并Double method( String s )在同一个班,例如。
Ray Stojonic

2
也许你感到困惑method signaturemethod declaration
彼得Lawrey

@Ray我想指出的是,我在编辑最初的问题之前就写了我的答案,他所要问的只是它是签名的一部分,我想确保他没有在不列出姓名的情况下写公共名()。返回类型(实话实说,他可以通过编写一个简单的程序来测试它来回答自己的问题)
Jeff Hawthorne 2013年


1

使用AspectJ(org.aspectj.lang.reflect.MethodSignature),它确实具有返回类型


1

方法签名包括返回类型。

当必须检查重复项时,编译器将忽略它。对于Java,使用两种签名仅返回类型不同的方法是非法的。

试试看:

public class Called {
    public String aMethod() {
        return "";
    }
}

public class Caller {
    public static void main(String[] main) {
        aMethod();
    }
    public static void aMethod() {
        Called x = new Called();
        x.aMethod();
    }
}

生成项目,转到bin目录,将Caller.cass复制到某个地方。然后更改调用的方法:

public int aMethod() {
    return 0;
}

生成项目后,您将看到Called.class和Caller.class都有新的时间戳。替换上面的Caller.class并运行项目。您将有一个例外:

java.lang.NoSuchMethodError: it.prova.Called.aMethod()Ljava/lang/String;


0

如果您尝试运行在eclipse上提到的代码,您将得到一个答案,即Java编译器将查找哪些元素来区分Java方法:

class Foo {
    public int  myMethod(int param) {
        return param;}
    public char *myMethod*(int param) { //this line throws an error 
        return param;
    }
}

引发的错误是:类型为Foo的重复方法myMethod(int)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.