Чи підпис методу на 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/02/…
Пітер Лорі

Відповіді:


146

Цитування з Документів Oracle :

Визначення: Два компоненти декларації методу містять підпис методу - ім'я методу та типи параметрів.

введіть тут опис зображення

Оскільки питання було відредаговано, щоб включити цей приклад:

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

Ні, компілятор не знатиме різниці, оскільки їх підпис: myMethod(int param)однаковий. Другий рядок:

    public char myMethod(int param) {}

дасть вам можливість помилки: метод вже визначений у класі , що додатково підтверджує вищевикладене твердження.


Отже, ви маєте на увазі, що у нас не може бути двох методів у класі, що мають однакову назву методу, однакові параметри з різними типами повернення?
Kasun Siyambalapitiya

6
@KasunSiyambalapitiya курси ми не можемо. Як компілятор дізнається, який із методів викликати у такому сценарії foo.bar(baz);?
Колюня

@Jops, що робити, якщо у нас є ключове слово кидок? Чи належить він і до підпису?
Акіла Амарасінгхе

19

Чи підпис методу класу на Java включає тип повернення?

У Java це не так, але в цьому JVM це робить, що може призвести до явної плутанини.

Чи підпис методу інтерфейсу на Java включає тип повернення?

Те саме, що і для класових методів.

Або лише список методу та список параметрів?

Назва методу та типи параметрів для Java. Наприклад, примітки та назви параметрів не мають значення.


1
Що ви маєте на увазі під "У Java це не так, але в JVM це робить". Не могли б ви детальніше розповісти, як у JVM?
Tarun Maganti

3
@TarunMaganti JVM включає тип повернення в підпис методу. Ява як мова не відповідає.
Пітер Лорі

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). Як такий у випадку клонування, значення має аргумент не повертати тип.
Huy Le


7

Спеціальність мови Java говорить

Два способи мають однаковий підпис, якщо вони мають однакове ім’я та типи аргументів.

таким чином Ні, тип return не є частиною підпису методу.


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. Це "ті ж назви та типи аргументів". Модифікатор доступу та ім'я параметра також не є частиною підпису методу.
Пітер Лорі

якщо це тестове питання, це добре, але якщо я пишу програму, я не пишу публічний getString (), я пишу публічний String getString ()
Джефф Хоторн

1
Модифікатор доступу, тип повернення та типи викидів не є частиною підпису, тому, наприклад, ви не можете мати String method( String s )і Double method( String s )в тому самому класі.
Рей Стожоніч

2
Можливо, ви плутаєте method signatureзmethod declaration
Пітер Лорі

@Ray Я хотів би зазначити, я писав свою відповідь, перш ніж редагував початкове запитання, все, що він запитав, це це частина підпису, я хотів переконатися, що він не намагається написати публічне ім’я (), не вказуючи тип повернення (правду кажучи, він міг відповісти на власне запитання, просто написавши просту програму для тестування)
Джефф Хоторн


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

Створіть проект, перейдіть до каталогу бін, скопіюйте кудись Caller.cass . Потім змініть названий метод:

public int aMethod() {
    return 0;
}

Побудувавши проект, ви побачите, що і Called.class, і Caller.class мають нову часову позначку. Замініть клас Caller.clas вище та запустіть проект. У вас буде виняток:

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

Викинута помилка: Дублікат методу myMethod (int) типу Foo.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.