Javaのメソッドのシグネチャには戻り値の型が含まれていますか?


102

Javaクラス/インターフェースのメソッドシグネチャには、戻り値の型が含まれていますか?

例:

Javaはこれら2つのメソッドの違いを知っていますか?

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

それとも、問題になるのはメソッド名とパラメータリストだけでしょうか?


7
ちなみに、JVMはシグネチャで戻り値の型を使用してそれらを選択的に呼び出すため、Java 6のジェネリックの処理にバグがあり、両方のメソッドを持つことができました。これはJava 7で修正されました。vanillajava.blogspot.co.uk/ 2011/02 /…
Peter Lawrey

回答:


146

Oracle Docsからの引用:

定義:メソッド宣言の2つのコンポーネントは、メソッドシグネチャ(メソッドの名前とパラメータータイプ)で構成されます。

ここに画像の説明を入力してください

この例を含むように質問が編集されたので、

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

いいえ、シグネチャmyMethod(int param)は同じなので、コンパイラは違いを認識しません。2行目:

    public char myMethod(int param) {}

エラーが発生します:メソッドはすでにclass定義されています。これにより、上記のステートメントがさらに確認されます。


つまり、同じメソッド名、異なる戻り値型を持つ同じパラメーターを持つクラスに2つのメソッドを含めることはできないということですか?
Kasun Siyambalapitiya

6
@KasunSiyambalapitiyaコースのことはできません。コンパイラーは、このようなシナリオで呼び出すメソッドをどのようにして知るのでしょうfoo.bar(baz);か?
Kolyunya

@ Jops、throwsキーワードがある場合はどうなりますか?それも署名に属していますか?
Akila Amarasinghe

19

Javaのクラスメソッドシグネチャには戻り値の型が含まれていますか?

Javaではそうしませんが、このJVMではそうします。これは明らかな混乱を招きます。

Javaのインターフェイスメソッドシグネチャには戻り値の型が含まれていますか?

クラスメソッドと同じです。

または、メソッド名とパラメータリストのみですか?

Javaのメソッド名とパラメータータイプ。たとえば、パラメータの注釈と名前は重要ではありません。


1
「JavaではそうではないがJVMではそうだ」とはどういう意味ですか。JVMでの方法について詳しく教えてください。
Tarun Maganti 2017

3
@TarunMaganti JVMでは、メソッドシグネチャに戻り値の型が含まれています。言語としてのJavaにはありません。
Peter Lawrey 2017

3
@xyzこれは、バイトコードを読み取ってもJavaコードでは読み取れないものです。任意のバイトコードがこれを示しています。
Peter Lawrey 2018年

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)であると考えるかもしれません。このように、クローンの場合、違いは、戻り値の型ではなく引数です。
Huy Le


7

Java言語仕様は言う

名前と引数の型が同じである2つのメソッドは、同じシグネチャを持ちます。

したがって、いいえ、戻り値の型はメソッドシグネチャの一部ではありません。


6

JAVAおよび他の多くの言語では、変数なしでメソッドを呼び出して戻り値を保持できます。戻り値の型がメソッドシグネチャの一部である場合、戻り値を保持する変数を指定せずに呼び出すときにどのメソッドが呼び出されるかを知る方法はありません。


4

Bro、Javaでは、名前とパラメーターでメソッドを呼び出すために使用します。

myMethod(20、40)

したがって、JAVAは、対応する宣言(name + param)で一致する類似のもののみを検索します。これが、メソッドシグネチャにメソッドの名前とパラメータのみが含まれている理由です。:)



3

いいえ、Javaではメソッドシグネチャに戻り値の型は含まれていませんが、宣言には含まれています。

public             String         getString(String myString)

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

以下のフィードバックに基づいて編集:)


1
それはJLSが言うことではありません。「同じ名前と引数型」です。アクセス修飾子とパラメーター名もメソッドシグネチャの一部ではありません。
Peter Lawrey、2013

テスト問題であれば問題ないが、プログラムを作成しているのにpublic getString()を作成していないのであれば、public String getString()を作成している
Jeff Hawthorne

1
アクセス修飾子、戻り値の型とタイプ(複数可)を投げあなたが持つことができない理由は署名の一部ではないString method( String s )Double method( String s )同じクラスで、インスタンスのために。
Ray Stojonic 2013

2
多分あなたは混乱method signatureしていますmethod declaration
ピーター・ローリー

@Ray私は注意したいのですが、彼が最初の質問を編集する前に私の答えを書きました、彼が尋ねたのはそれが署名の一部であるだけでした戻り値の型(正直に言うと、彼はそれをテストする簡単なプログラムを書くだけで自分の質問に答えることができたでしょう)
Jeff Hawthorne


1

AspectJ(org.aspectj.lang.reflect.MethodSignature)を使用すると、戻り値の型があります


1

メソッドシグネチャには、戻り値のタイプが含まれます。

重複をチェックする必要がある場合、コンパイラはそれを無視します。Javaの場合、シグネチャが戻り値の型だけが異なる2つのメソッドを持つことは違法です。

それを試してください:

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)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.