Chữ ký của một phương thức trong Java có bao gồm kiểu trả về của nó không?


102

Chữ ký phương thức trong một lớp / giao diện Java có bao gồm kiểu trả về của nó không?

Thí dụ:

Java có biết sự khác biệt giữa hai phương pháp đó không:

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

Hoặc có thể chỉ có tên phương thức và danh sách tham số là quan trọng?


7
Nhân tiện, có một lỗi trong việc xử lý các generic trong Java 6 cho phép bạn có cả hai phương thức, vì JVM sử dụng kiểu trả về trong chữ ký và gọi chúng một cách có chọn lọc. Điều này đã được cố định trong Java 7. vanillajava.blogspot.co.uk/2011/02/...
Peter Lawrey

Câu trả lời:


146

Trích dẫn từ Oracle Docs :

Định nghĩa: Hai trong số các thành phần của khai báo phương thức bao gồm chữ ký phương thức — tên phương thức và các kiểu tham số.

nhập mô tả hình ảnh ở đây

Vì câu hỏi đã được chỉnh sửa để đưa vào ví dụ này:

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

Không, trình biên dịch sẽ không biết sự khác biệt, vì chữ ký của họ: myMethod(int param)giống nhau. Dòng thứ hai:

    public char myMethod(int param) {}

sẽ cung cấp cho bạn lỗi có thể: phương thức đã được định nghĩa trong lớp , điều này xác nhận thêm câu lệnh trên.


Vậy ý bạn là chúng ta không thể có hai phương thức trong lớp có cùng tên phương thức, cùng tham số với các kiểu trả về khác nhau?
Kasun Siyambalapitiya

6
@KasunSiyambalapitiya của Cource, chúng tôi không thể. Làm thế nào trình biên dịch biết được phương thức nào được gọi trong một kịch bản như thế này foo.bar(baz);?
Kolyunya

@ Rất tiếc, điều gì sẽ xảy ra nếu chúng ta có từ khóa ném? Nó có thuộc cả chữ ký không?
Akila Amarasinghe

19

Chữ ký phương thức lớp trong Java có bao gồm kiểu trả về không?

Trong Java thì không nhưng trong JVM này, nó có thể dẫn đến sự nhầm lẫn rõ ràng.

Chữ ký phương thức giao diện trong Java có bao gồm kiểu trả về không?

Tương tự như đối với các phương thức lớp.

Hay chỉ có tên phương thức và danh sách tham số?

Tên phương thức và các kiểu tham số cho Java. Ví dụ: chú thích tham số và tên không quan trọng.


1
Ý bạn là gì khi "Trong Java thì không nhưng trong JVM thì có.". Bạn có thể nói rõ hơn về cách thức trong JVM?
Tarun Maganti

3
@TarunMaganti JVM bao gồm kiểu trả về trong chữ ký phương thức. Java như một ngôn ngữ thì không.
Peter Lawrey

3
@xyz đây là thứ bạn có thể thấy bằng cách đọc mã byte nhưng không phải mã Java. Bất kỳ mã byte nào cũng hiển thị điều này.
Peter Lawrey

8

Ở mức bytecode, "kiểu trả về" là một phần của chữ ký phương thức. Xem xét điều này

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

trong bytecode có 2 phương thức clone ()

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

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

chúng chỉ khác nhau theo loại trả lại.


1
điều này gây hiểu lầm vì phương thức instance mặc nhiên có instance là tham số đầu tiên. Một khi có thể nghĩ rằng om (a) trong thực tế là m (o, a). Như vậy trong trường hợp sao chép, điều tạo ra sự khác biệt là đối số không phải kiểu trả về.
Huy Lê


7

Thông số ngôn ngữ Java cho biết

Hai phương thức có cùng chữ ký nếu chúng có cùng tên và kiểu đối số.

do đó Không, kiểu trả về không phải là một phần của chữ ký phương thức.


6

Trong JAVA và nhiều ngôn ngữ khác, bạn có thể gọi một phương thức không có biến để giữ giá trị trả về. Nếu kiểu trả về là một phần của chữ ký phương thức, không có cách nào để biết phương thức nào sẽ được gọi khi gọi mà không chỉ định giá trị trả về giữ biến.


4

Anh bạn, Trong java, chúng tôi sử dụng để gọi các phương thức bằng tên của chúng và các tham số của chúng chỉ để sử dụng chúng trong mã của chúng tôi, như

myMethod (20, 40)

vì vậy, JAVA chỉ tìm kiếm các nội dung tương tự phù hợp trong khai báo tương ứng của chúng (tên + tham số), đây là lý do tại sao chữ ký phương thức chỉ bao gồm tên và các tham số của phương thức. :)



3

không, trong Java, chữ ký phương thức không bao gồm kiểu trả về, nhưng khai báo thì có.

public             String         getString(String myString)

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

được chỉnh sửa dựa trên phản hồi bên dưới :)


1
Đó không phải là những gì JLS nói. Nó là "cùng tên và các kiểu đối số." Công cụ sửa đổi truy cập và tên tham số cũng không phải là một phần của chữ ký phương thức.
Peter Lawrey

nếu đó là một câu hỏi kiểm tra đó là tốt, nhưng nếu tôi đang viết một chương trình tôi không viết getString công cộng (), tôi đang viết public String getString ()
Jeff Hawthorne

1
Công cụ sửa đổi quyền truy cập, kiểu trả về và (các) kiểu ném không phải là một phần của chữ ký, đó là lý do tại sao bạn không thể có String method( String s )Double method( String s )trong cùng một lớp, chẳng hạn.
Ray Stojonic

2
Có lẽ bạn đang bối rối method signaturevớimethod declaration
Peter Lawrey

@Ray tôi muốn lưu ý, tôi đã viết câu trả lời của mình trước khi anh ấy chỉnh sửa câu hỏi đầu tiên, tất cả những gì anh ấy hỏi là nó là một phần của chữ ký, tôi muốn đảm bảo anh ấy không cố gắng viết tên công khai () mà không liệt kê kiểu trả về (sự thật mà nói, anh có thể trả lời câu hỏi của riêng mình chỉ bằng cách viết một chương trình đơn giản để kiểm tra nó)
Jeff Hawthorne


1

Sử dụng AspectJ (org.aspectj.lang.reflect.MethodSignature), nó có kiểu trả về


1

PHƯƠNG PHÁP CHỮ KÝ BAO GỒM KIỂU TRỞ LẠI.

Trình biên dịch bỏ qua nó khi phải kiểm tra các bản sao. Đối với Java là bất hợp pháp khi có hai phương thức với chữ ký chỉ khác nhau bởi kiểu trả về.

Hãy thử điều đó:

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

Xây dựng dự án, vào thư mục bin, sao chép Caller.cass vào đâu đó. Sau đó, thay đổi phương thức được gọi:

public int aMethod() {
    return 0;
}

Xây dựng dự án, bạn sẽ thấy rằng cả Called.class và Caller.class đều có dấu thời gian mới. Thay thế lớp Caller.class ở trên và chạy dự án. Bạn sẽ có một ngoại lệ:

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


0

Nếu bạn cố gắng chạy mã bạn đã đề cập trên eclipse, bạn sẽ có câu trả lời về việc trình biên dịch java tìm kiếm những yếu tố nào để phân biệt giữa các phương thức java:

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

Lỗi được đưa ra là: Phương thức trùng lặp myMethod (int) trong kiểu Foo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.