Apakah tanda tangan metode di Java menyertakan tipe kembaliannya?

102

Apakah tanda tangan metode dalam kelas / antarmuka Java menyertakan tipe kembaliannya?

Contoh:

Apakah Java mengetahui perbedaan antara kedua metode tersebut:

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

Atau mungkin hanya nama metode dan daftar parameter yang penting?

faressoft
sumber
7
Ngomong-ngomong, ada bug dalam penanganan generik di Java 6 yang memungkinkan Anda memiliki kedua metode tersebut, karena JVM memang menggunakan tipe kembalian dalam tanda tangan dan memanggilnya secara selektif. Ini telah diperbaiki di Jawa 7. vanillajava.blogspot.co.uk/2011/02/…
Peter Lawrey

Jawaban:

146

Mengutip dari Oracle Docs :

Definisi: Dua komponen deklarasi metode terdiri dari tanda tangan metode — nama metode dan jenis parameter.

masukkan deskripsi gambar di sini

Sejak pertanyaan diedit untuk memasukkan contoh ini:

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

Tidak, kompilator tidak akan tahu perbedaannya, karena tanda tangannya: myMethod(int param)sama. Baris kedua:

    public char myMethod(int param) {}

akan memberi Anda kesalahan: metode sudah ditentukan di kelas , yang selanjutnya menegaskan pernyataan di atas.

Jops
sumber
Jadi maksud Anda kita tidak dapat memiliki dua metode di kelas yang memiliki nama metode yang sama, parameter yang sama dengan tipe kembalian yang berbeda?
Kasun Siyambalapitiya
6
@KasunSyambalapitiya tentu saja kita tidak bisa. Bagaimana kompilator mengetahui metode mana yang dipanggil dalam skenario seperti ini foo.bar(baz);?
Kolyunya
@Jops, bagaimana jika kita memiliki kata kunci lemparan? Apakah itu milik tanda tangan juga?
Akila Amarasinghe
19

Apakah tanda tangan metode kelas di Java termasuk tipe kembalian?

Di Java, tidak, tetapi di JVM ini, hal itu dapat menyebabkan kebingungan yang jelas.

Apakah tanda tangan metode antarmuka di Java termasuk tipe kembali?

Sama seperti untuk metode kelas.

Atau hanya nama metode dan daftar parameter?

Nama metode dan tipe parameter untuk Java. Misalnya, anotasi parameter dan nama tidak penting.

Peter Lawrey
sumber
1
Apa yang Anda maksud dengan "Di Jawa tidak, tetapi di JVM itu." Bisakah Anda menjelaskan tentang bagaimana di JVM?
Tarun Maganti
3
@TarunMaganti JVM menyertakan tipe kembalian dalam tanda tangan metode. Java sebagai bahasa tidak.
Peter Lawrey
3
@xyz ini adalah sesuatu yang dapat Anda lihat dengan membaca kode byte tetapi bukan kode Java. Kode byte apa pun menunjukkan ini.
Peter Lawrey
8

Pada tingkat bytecode, "tipe pengembalian" adalah bagian dari tanda tangan metode. Pertimbangkan ini

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

dalam bytecode ada 2 metode clone ()

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

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

mereka hanya berbeda dalam tipe pengembalian.

Evgeniy Dorofeev
sumber
1
ini menyesatkan karena metode instance secara implisit memiliki instance sebagai parameter pertama. Suatu ketika mungkin berpikir bahwa om (a) sebenarnya adalah m (o, a). Dengan demikian dalam kasus klon, yang membedakan adalah argumen bukan tipe kembalian.
Huy Le
7

Spesifikasi Bahasa Java mengatakan

Dua metode memiliki tanda tangan yang sama jika memiliki nama dan tipe argumen yang sama.

jadi Tidak, tipe pengembalian bukan bagian dari tanda tangan metode.

PermGenError
sumber
6

Di JAVA dan banyak bahasa lainnya, Anda dapat memanggil metode tanpa variabel untuk menampung nilai yang dikembalikan. Jika tipe kembalian adalah bagian dari tanda tangan metode, tidak ada cara untuk mengetahui metode mana yang akan dipanggil saat memanggil tanpa menentukan variabel yang menahan nilai kembalian.

Huy Le
sumber
4

Bro, Di java, kami menggunakan untuk memanggil metode dengan namanya dan parameternya hanya untuk menggunakannya dalam kode kami, seperti

myMethod (20, 40)

jadi, JAVA hanya mencari hal serupa yang cocok di deklarasi yang sesuai (nama + param), inilah mengapa tanda tangan metode hanya menyertakan nama dan parameter metode. :)

NIKHIL CHAURASIA
sumber
3

Tanda tangan metode hanya nama dan daftar parameter.

Ray Stojonic
sumber
3

tidak, di Java tanda tangan metode tidak menyertakan tipe kembalian, tetapi deklarasi menyertakannya.

public             String         getString(String myString)

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

diedit berdasarkan umpan balik di bawah :)

Jeff Hawthorne
sumber
1
Bukan itu yang dikatakan JLS. Ini adalah "nama dan tipe argumen yang sama." Pengubah akses dan nama parameter juga bukan bagian dari tanda tangan metode.
Peter Lawrey
jika itu adalah pertanyaan tes, itu bagus, tetapi jika saya menulis program, saya tidak menulis getString publik (), saya menulis String getString () publik
Jeff Hawthorne
1
Pengubah akses, tipe kembalian, dan tipe lemparan bukan bagian dari tanda tangan, itulah sebabnya Anda tidak bisa memiliki String method( String s )dan berada Double method( String s )di kelas yang sama, misalnya.
Ray Stojonic
2
Mungkin Anda bingung method signaturedenganmethod declaration
Peter Lawrey
@Ray saya ingin mencatat, saya menulis jawaban saya sebelum dia mengedit pertanyaan awal, yang dia tanyakan hanyalah itu bagian dari tanda tangan, saya ingin memastikan dia tidak mencoba menulis nama publik () tanpa mencantumkan tipe pengembalian (sejujurnya, dia bisa menjawab pertanyaannya sendiri hanya dengan menulis program sederhana untuk mengujinya)
Jeff Hawthorne
2

Jenis pengembalian tidak termasuk dalam tanda tangan metode. Hanya pengembalian metode. Hanya nama metode dan Parameter yang ditentukan sebagai tanda tangan metode.

Referensi: Oracle Docs 'Defining Methods'

Kandy
sumber
1

Menggunakan AspectJ (org.aspectj.lang.reflect.MethodSignature), ia memang memiliki tipe kembalian

devnull
sumber
1

METODE TANDA TANGAN TERMASUK JENIS PENGEMBALIAN.

Kompilator mengabaikannya ketika harus memeriksa duplikat. Untuk Java adalah ilegal untuk memiliki dua metode dengan tanda tangan yang dibedakan hanya dengan tipe kembalian.

Coba itu:

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

Bangun proyek, buka direktori bin, salin Caller.cass di suatu tempat. Kemudian ubah metode yang dipanggil:

public int aMethod() {
    return 0;
}

Bangun proyek, Anda akan melihat bahwa Called.class dan Caller.class memiliki stempel waktu baru. Ganti Caller.class di atas dan jalankan proyek. Anda akan memiliki pengecualian:

java.lang.NoSuchMethodError: it.prova.Called.aMethod()Ljava/lang/String;
Lucio Menci
sumber
0

Jika Anda mencoba menjalankan kode yang Anda sebutkan di eclipse, Anda akan mendapat jawaban tentang elemen apa yang dicari oleh java compiler untuk membedakan di antara metode java:

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

Kesalahan yang dilemparkan adalah: Metode duplikat myMethod (int) dengan tipe Foo.

Nishant_Singh
sumber