2016-05-01 39 views
20

Czy jest jakaś różnica między następującymi dwiema metodami?Powrót metody, w bloku "try" lub po "catch" bloku?

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

Podoba mi się drugi fragment, ponieważ uważam go za bardziej przejrzysty (i bardziej przejrzysty). Nie wydaje mi się, żeby to miało jakikolwiek wpływ na wydajność. – Eran

+1

Najpierw podoba mi się ten pierwszy, z powodu tego, co się stanie, jeśli zdecydujesz się obsługiwać wyjątek lokalnie, zamiast go ponownie rzucać. – njzk2

Odpowiedz

23

Rozważ te przypadki, w których nie jesteś powracających stałą ekspresję:

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 pierwszego. Drugi jest bardziej gadatliwy i może powodować pewne zamieszanie podczas debugowania.

Jeśli test() nieprawidłowo zwraca null i widzisz toReturn są inicjowane null, można by pomyśleć, że problem jest w test() (zwłaszcza gdy test() nie jest to tylko prosty przykład jak tego).

Mimo że może zwrócić tylko null, jeśli doSomething zwraca null. Ale to może być trudne do zobaczenia na pierwszy rzut oka.


Następnie można argumentować, że w imię spójności, to lepiej zawsze użyciu pierwszego formularza.

4

Nope nie ma różnicy między obiema metodami. Zwróci true wartość w obu przypadkach skutecznie poprzez wznowienie przepływu programu, jak tylko zostanie obsłużony i wyjątek. Złapanie będzie dostępne tylko w przypadku wystąpienia wyjątku.

-5

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

+0

Jakiś dowód tego? –

+0

korzystając z tego kodu, możesz to udowodnić: \t long startTime, endTime, duration; \t \t StartTime = System.nanoTime(); \t \t test2(); // lub test1() \t \t endTime = System.nanoTime(); – ABBOne

+2

to nie jest dobry sposób na porównywanie aplikacji –

3

Nie ma 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.

W związku z tym pierwszy z nich jest uważany za lepszy z punktu widzenia dobrych praktyk.

+3

Czy możesz przestać przetwarzać tę starą mądrość, która nie jest już istotna stackoverflow.com/questions/36707/should-a -funkcja-ma-tylko-jeden-return-instrukcja –

2

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 to naprawdę nie ma znaczenia. Ta metoda jest wystarczająco krótka, aby zrozumieć od razu, co się dzieje, co jest związane z tym itp.

Jednak w przypadku dłuższych metod przepływ jest łatwiejszy do zrozumienia w pierwszym przykładzie. Moim zdaniem. Utrzymuje powiązany kod i powiązane scenariusze. Kiedy czytasz tę metodę, normalny przepływ wykonania nie jest zepsuty przez blok catch, przez co staje się bardziej oczywisty i "płynny".

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.