Подтвердить что ты не робот

Java - почему нет перегрузки метода на основе возвращаемого типа?

Я знаю, что это невозможно, но может ли кто-нибудь дать теорию о том, почему Java предпочла не поддерживать это? Я спрашиваю, потому что я просто столкнулся с ситуацией, когда, по-моему, было бы неплохо иметь.

4b9b3361

Ответ 1

Поскольку вам не требуется фиксировать возвращаемое значение метода на Java, в этом случае компилятор не может решить, какую перегрузку использовать. Например.

boolean doSomething() { ... }

int doSomething() { ... }

doSomething(); // which one to call???

Ответ 2

Интересным аспектом этого вопроса является тот факт, что язык Java запрещает методы перегрузки только с помощью типа возврата. Но не JVM:

Обратите внимание, что может быть больше одного метод сопоставления в классе, потому что в то время как язык Java запрещает класс для объявления нескольких методов с помощью та же подпись, но другая типы возврата, виртуальная машина Java не. Это повышает гибкость в виртуальной машине можно использовать для реализовать различные языковые функции. Например, ковариантные возвращения могут быть реализованы с использованием мостовых методов; моста и способ переопределенные будут иметь одинаковые подписи, но разные типы возврата.

От: Class.getMethod(String, Class...)

Ответ 4

Я задавался вопросом, почему они тоже не поддерживают это. Конечно, если вы проигнорируете возвращаемое значение, компилятор не сможет узнать, чего вы хотели. Но та же двусмысленность, которая возникает с передачей нулей. Как:

String doSomething(String s) { ... }
String doSomething(Integer s) { ... }
...
String out=doSomething(null);

В этом случае компилятор просто жалуется на то, что вызов неоднозначен, и вы должны решить его, нажав нуль, например:

String out=doSomething((String)null);

Вы можете сделать то же самое с перегрузкой по типу возврата:

String getSomething() { ... }
Integer getSomething() { ... }
...
Integer n=getSomething();

предположительно вызовет вторую функцию.

getSomething();

будет неоднозначным (и в этом примере, вероятно, бесполезным, если только у него не было побочных эффектов, но эта другая история), поэтому вам нужно сказать:

(String) getSomething();

Более реалистично, возможно:

if ((String) getSomething()==null) ...

Но это простой случай. Я вижу, что компилятор-писатель не хочет поддерживать это, потому что он может оказаться очень сложным в чем-то другом, кроме простого назначения. Например, рассмотрим:

String getSomething() { ... };
Integer getSomething() { ... };
String getOtherthing() { ... };
...
if (getSomething().equals(getOtherthing())) ...

Компилятор должен был бы выяснить, что и String, и Integer имеют равные функции, поэтому один из них действителен в этой точке. Тогда он должен был заметить, что getOtherthing - это String, а Integer.equals(String) маловероятен, поэтому, вероятно, то, что хотел автор, было String.equals(String). Do-able, но в этот момент я начинаю видеть, что в общем случае это может быть зверь.

Затем добавим:

Integer getOtherthing() { ... };

Теперь, что делает компилятор с этим оператором IF? Он может использовать версии String обеих функций или Integer, но не String одного и целого другого. В этот момент он должен будет настаивать на том, чтобы бросить, чтобы сказать, что, я думаю. Но сложность действительно выходит из-под контроля.

И если это сложно для компилятора, чтобы понять, что вы на самом деле имеете в виду, представьте, как это будет выглядеть для другого программиста, который не может найти все сигнатуры функций так быстро, как это может сделать компилятор.

Ответ 5

Это потому, что вы можете игнорировать возвращаемое значение.

Ответ 6

Хотя теоретически это возможно, он не использовался в Java по той же причине, что и не использовался в С++; а именно, было обнаружено, что перегрузки, основанные на типах возвратов, как правило, более сбивают с толку разработчиков, преимущество является незначительным по сравнению с затратами на его реализацию, и оно было бы неоднозначным в случае, когда возвращаемый тип не присваивается стоимость. По этим причинам перегрузка на основе возвращаемого типа не поддерживается.

Ответ 7

Я думаю, что одна из причин заключается в том, что в большинстве случаев вы можете определить возвращаемый тип функции только после выполнения функции, а не перед этим процессом. Таким образом, это не поможет вам решить, какую перегруженную функцию вызывать только на основе разных типов возвращаемых функций.

Ответ 8

функция перегрузки только на основе типа возврата запутывает компилятор для различения вызовов, потому что во время вызова вы не указываете тип возврата, как в случае с параметрами, поэтому вы предоставляете только список параметров, и этот список параметров является единственным способом для компилятора различать вызовы функций, а возвращаемое значение принимается при завершении функции, поэтому тип возврата не вносит вклад в подпись функции

Ответ 9

Поскольку Java может отличать значение возвращаемого значения к целевой переменной, поэтому он не знает, в какой тип переменной вы сохраняете возвращаемое значение функции.