Pytanie Powrót z metody, w bloku "try" lub po "catch" bloku?


Czy jest jakaś różnica między następującymi dwiema metodami?

Który z nich jest lepszy i dlaczego?

Prg1:

public static boolean test() throws Exception {
    try {
        doSomething();
        return true;
    } catch (Exception e) {
        throw new Exception("No!");
    }    
}

Prg2:

public static boolean test() throws Exception {
    try {
        doSomething();
    } catch (Exception e) {
        throw new Exception("No!");
    }
    return true;    
}

21
2018-05-01 10:24


pochodzenie


Bardziej podoba mi się ten drugi fragment, ponieważ uważam go za czystszy (i bardziej przejrzysty). Nie wydaje mi się, żeby to miało jakikolwiek wpływ na wydajność. - Eran
Pierwszy lepiej mi się podoba, z powodu tego, co się stanie, jeśli zdecydujesz się obsługiwać wyjątek lokalnie, zamiast go ponownie rzucać. - njzk2


Odpowiedzi:


Rozważ te przypadki, w których nie zwracasz stałego wyrażenia:

Przypadek 1:

public static Val test() throws Exception {
    try {
        return doSomething();
    } catch (Exception e) {
        throw new Exception("No!");
    }
    // Unreachable code goes here
}

Przypadek 2:

public static Val test() throws Exception {
    Val toReturn = null;
    try {             
        toReturn = doSomething();
    } catch (Exception e) {
        throw new Exception("No!");
    }
    return toReturn;
}

Wolałbym pierwszy. Drugi jest bardziej gadatliwy i może powodować pewne zamieszanie podczas debugowania.

Gdyby test() niepoprawnie zwraca nulli widzisz toReturn być zainicjowanym na null, możesz pomyśleć, że problem jest w toku test() (zwłaszcza gdy test() nie jest prostym przykładem tego typu).

Mimo że może tylko wrócić null gdyby doSomething zwraca null. Ale to może być trudne do zobaczenia na pierwszy rzut oka.


Można by wtedy argumentować, że dla zachowania spójności lepiej zawsze użyj pierwszego formularza.


23
2018-05-01 11:08





Nie ma żadnej różnicy między obiema metodami. Zwróci wartość rzeczywistą w obu przypadkach, skutecznie wznawiając przepływ programu, gdy tylko zostanie rozpatrzony wyjątek i wyjątek. Catch będzie dostępny tylko wtedy, gdy wystąpi wyjątek.


4
2018-05-01 10:37





Nie ma żadnej różnicy funkcjonalnej. Oba programy zachowują się w ten sam sposób. To tylko kwestia stylu kodowania i osobistego gustu.

Jako dobrą praktykę lepiej jest mieć jedno oświadczenie zwrotne dla każdej metody - na końcu metody, zamiast pośredniej. W przypadku długich bloków kodu, ten styl sprawia, że ​​kod jest bardziej czytelny i łatwiejszy do utrzymania w przyszłości, gdy autor (lub ktoś inny) musi wprowadzić zmiany w kodzie.

Dlatego też pierwsze z nich uważa się za lepsze z punktu widzenia dobrej praktyki.


3
2018-05-01 10:43



Mógłbyś przestać przetwarzać tę starożytną mądrość, która nie jest już istotna stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement - Esben Skov Pedersen


Zakładam, że to jest ogólne pytanie. W przeciwnym razie mogę wypowiedzieć się na temat innych aspektów twojej metody (metod).

Myślę, że w przypadku lub małych metod takich jak te nie ma to znaczenia. Ta metoda jest wystarczająco krótka, aby natychmiast zrozumieć, co się dzieje, co jest związane z czymś itp.

Jednak w przypadku dłuższych metod przepływ jest o wiele łatwiejszy do naśladowania w pierwszym przykładzie. W mojej opinii. Utrzymuje powiązany kod i powiązane scenariusze. Kiedy czytasz tę metodę, normalny przepływ wykonania nie jest zepsuty przez catch blok, czyniąc go bardziej oczywistym i "płynnym".

public static boolean test() throws Exception {
    try {
        doSomething();
        return true;
    } catch (Exception e) {
        throw new Exception("No!");
    }    
}

Ale nie będę generalizować tego dla wszystkich metod; wszystko zależy od kontekstu.


2
2018-05-01 22:31





Nie ma różnicy, ale pierwszy Prg1 jest szybszy niż Prg2.


-5
2018-05-01 10:40



Jakiś dowód na to? - Po-ta-toe
używając tego kodu, możesz to udowodnić: long startTime, endTime, duration; startTime = System.nanoTime (); test2 (); // lub test1 () endTime = System.nanoTime (); - ABBOne
to nie jest dobry sposób na porównywanie aplikacji - Po-ta-toe
dodając dane bezpośrednio do kodu, faktycznie wpływasz na działanie kodu. Twój program musi teraz wykonywać kroki, których nie powinien. Może to zmienić sposób, w jaki kompilator generuje IL - Po-ta-toe
Widzieć stackoverflow.com/q/504103/3004881 - Dan Getz