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

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

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

    boolean doSomething() { ... } int doSomething() { ... } doSomething(); // which one to call??? 

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

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

    From: Class.getMethod (String, Class …)

    Я думаю, вы можете найти решение в следующей ссылке.

    Перегрузка функций по типу возврата?

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

     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 одного и целого другого. В этот момент он должен будет настаивать на том, чтобы бросить, чтобы сказать, что, я думаю. Но сложность действительно выходит из-под контроля.

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

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

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

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

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

    Перегрузка метода использует метод polymorphismа времени компиляции. Метод переопределения использует метод polymorphismа времени выполнения.

    Перегрузка метода:

    Как сказано в предыдущих ответах, java не поддерживает перегрузку метода с использованием другого типа возвращаемого значения и тех же аргументов. Это связано с тем, что он должен определить, какой метод использовать во время компиляции. Чтобы устранить двусмысленность, они разработали метод перегрузки метода, подобный этому.

    Если нам действительно нужна перегрузка методов разными типами и одинаковыми аргументами, то в некоторой степени это возможно с заменой mehtod.

    Переопределение метода:

    Переопределение метода использует метод polymorphismа во время выполнения. Следовательно, какой метод выполнить не решен во время компиляции, и он определяется во время выполнения JVM.

    С типами возвращаемых вариантов совместного использования мы можем иметь другой тип возвращаемого значения в методе подclassа с теми же аргументами, что и базовый class.

    Пример ковариантного типа возврата:

      class BaseClass { BaseClass dosomething(){ System.out.println("Print BaseClass"); return this; } } class AnotherBaseClass extends BaseClass { @Override BaseClass dosomething(){ System.out.println("Print AnotherBaseClass"); return this; } } class SubClass extends AnotherBaseClass { @Override SubClass dosomething(){ /*Here SubClass is co-vairantreturn type*/ System.out.println("Print SubClass"); return this; } public static void main(String args[]){ SubClass s1 = new SubClass(); s1.dosomething(); } } 

    Вывод:

    Печать подclassа

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

    Давайте будем гением компьютера.