Gdzie rzucić wyjątkiem?

Gdzie rzucić wyjątkiem?
0

Cześć, mam małą rozkminę i nie daje mi to spokoju. Może to ja czegoś nie rozumiem, może ktoś pomoże ;)

Mam dwie klasy

Kopiuj
public class Base {
    private Something sth;

    public void something() {
        sth.setVar(22);
    }
}

Kopiuj
public class Something {
    private int var;

    public void setVar(int var) {
        if (var > 20) {
            throw new Exception("error");
        }
        this.var = var;
    }
}

oraz maina

Kopiuj
public class Main {
    public static void main(String[] args) {
	    Base b = new Base();
	    b.something();
    }
}

I teraz pytanie, gdzie lepiej rzucić wyjątkiem. Czy zależy to od czegoś? Równie dobrze mógłbym w metodzie something to zrobić.. Jest to prosty przykład i może w bardziej zaawansowanej 'apce' mógłbym coś wywnioskować...Czy wyjątek należy rzucać stricte w tej metodzie, gdzie nie może jakaś sytuacja wystąpić, czy może w metodzie sprawdzić czy wartość jest większa od 20 i tam rzucić wyjątkiem?

bakeraw2
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 5 lat
  • Postów:400
0

Powinieneś rzucić wyjątkiem w metodzie która operuje na przesłanych przez Ciebie danych- w twoim przypadku będzie to metoda setVar.
Większy problem jest z tym gdzie powinieneś go obsłużyć. W aplikacjach webowych z reguły wyrzuca się wyjątki niekontrolowane i obsługuje w ExceptionHandler.

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Albo nie rzuca się wcale, tylko zwraca wynik który mówi o tym że coś się nie powiodło (np. przez Either) albo, jeśli to jest faktycznie coś po czym nie da się łatwo podnieść, rzuca się jakiś runtime exception. Wyjątek jeśli już to oczywiście rzucasz tam gdzie wykryłeś błąd.

Generalnie rzucenie wyjątku sugeruje że chcesz to obsługiwać gdzieś dużo dużo wyżej albo ewentualnie że wywalił się konstruktor.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
TH
TH
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 4 lata
  • Postów:31
0

Wyrzuć wyjątek w metodzie, która przyjmuje dane wejściowe od Ciebie. W tym przypadku, w metodzie setVar() masz if który sprawdza argument var.

Jeśli będzie niepoprawny, możesz wyrzucić​ najlepiej jakiś Unchecked Exception np IllegalArgumentException.
Poczytaj o dobrych praktykach wyjątków w Clean Code ;)

edytowany 1x, ostatnio: thorbjorn
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:35 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Generalnie @Shalom pisze prawdę - ale nie całą. Wyjątki checked sa passe i to nieudany ekpseryment Javy.
Czyli albo zdarza się coś w stylu "cholera cały system nie działa i nic nie poradzę" - wtedy rzucasz RuntimeException.
Ale u Ciebie tu chodzi o walidację parametrów... wtedy ..

no kurde nie może być tak, że setVar zwraca void - co to kurde jest void? znaczy, że nic nie robi metoda? Wywal ją :-)
Lepiej jak zrobisz cos w tym stylu:

Kopiuj
public Either<Error, Something > setVar(int var) {
        if (var > 20) {
            return Either.left( new WrongValueError(var));
        }
        return Either.right( new Something(var));
    }

Takie podejście zmniejsza błędogenność i ułatwia testowanie.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Futurama
  • Postów:887
0

No dobra, ale co kiedy korzystamy z czystej Javy? Tam nie ma Either. Korzystamy z Optional i wywołujemy orElse()?
Może zróbmy na szybko taką bazę:

  • kiedy przekazać wyjątek wyżej? (deklaracja throws)
  • kiedy ręcznie rzucić wyjątkiem (IllegalArgumentException, NullPointerException [np. w kontruktorze])
  • kiedy rzucić RuntimeException?
  • kiedy zwrócić wartość defaultową?

Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
jarekr000000
Zabraniają Ci dociągać bibliotek?
Burdzi0
Niby nie, ale to komplikuje w pewien sposób projekt, zwłaszcza dla osób tak niedoświadczonych jak ja. Trzeba wiedzieć jak się z tego korzysta i jak się z tego korzysta poprawnie/wydajnie, stąd moje pytanie o ekwiwalent w czystej Javie. Czy to nie Ty zawsze odpowiadasz na pytanie czego się uczyć, żeby uczyć się Javy? ;)
jarekr000000
No ale akurat niestety w tym punkcie standardowe biblioteki Javy są bardziej skomplikowane od JavaSlang, albo mają braki - brak Either. Standardowe java.util powinno w tej chwili raczej być używane jak gdzieś walczysz o "cycle" -masz duże mutowalne listy i mapy. A dodatkowo Optional z java util - albo completableFuture to niestety katastrofy w API (i nie tylko).
Burdzi0
@jarekr000000: Może ujmę to troszkę inaczej. Ja dopiero zaczynam. Jakieś 1,5 roku. Wiem niewystarczająco, a jak dodam do tego jeszcze mniej z innej działki i połączę to mam jeden wielki bajzel, więc uczę się tylko tego pierwszego (nie komplikuję sobie, bo się nigdy nie nauczę). Co w takim razie polecasz? Ogarnąć to JavaSlang?
jarekr000000
Parę lat temu było tak, że Java bez Guavy nie miała sensu. Teraz nie ma sensu bez JavaSlang. Po prostu obowiązkowa biblioteka. Ogarnij JavaSlang zamiast zagłebiać się za bardzo w java.util. To drugie to wyższy level.
0

Nie będę zakładał nowego wątku, usmażę dwie pieczenie na jednym ogniu ;)

Chciałbym mieć taką sytuację, gdzie mam jakąś klasę i fabrykę, która zwraca obiekt tej klasy, ale chciałbym, żeby tylko poprzez fabrykę (statyczną metodę) była możliwość utworzenia nowego obiektu. Czy jest to w ogóle możliwe? Próbowałem zrobić zagnieżdżenie, i bawić się modyfikatorami dostępu, ale albo da się zwrócić obiekt poprzez fabrykę i poprzez konstruktor, albo wcale...

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Wyjątki checked sa passe i to nieudany ekpseryment Javy.

Nibyż to czemu?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
V-2
Trudno chyba znaleźć autorytet, który jeszcze by ich bronił. Zob. np. Uncle Bob w "Clean Code" czy Bruce Eckel. Nie jest kwestią przypadku, że nikt poza Javą tego (świetnego w teorii) rozwiązania nie skopiował. W praktyce programistycznej korzystanie z tej funkcji - w sposób zgodny z intencją autorów - jest według moich obserwacji rzadko spotykane.
PI
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 miesiące
  • Postów:2787
0
scibi92 napisał(a):

Wyjątki checked sa passe i to nieudany ekpseryment Javy.

Nibyż to czemu?

Według mnie, to checked wyjątki są okej, ale jeśli są bardzo "na dole" - jak otwieramy te połączenie SQLowe albo jakiś stream z/do pliku. Ale wyżej, w logice biznesowej, wymóg obsłużenia wyjątku jest męczący (jeśli sporo metod serwisowych by takowe rzucało)

edytowany 1x, ostatnio: Pinek
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@Smutny Rycerz prywatny konstruktor? ;)
@scibi92 w javie 1.7 to jeszcze jakoś szło, ale w javie 8 to można dostać białej gorączki jak chcesz gdzieś wrzucać method reference zamiast lambdy i protestuje że metoda rzuca wyjątkami ;) Ale generalnie jak rzucasz checked exception to zwykle chcesz go obsługiwać gdzieś bardzo blisko, a to znaczy ze równie dobrze można to zrobić Optionalem czy Either.
@Pinek jw, skoro chcesz obsługiwać to od razu to czemu wyjątek a nie Optional?

Z braku lepszych alternatyw mam zwykle w projekcie własne functional interface które są klonami tych standardowych function, supplier, consumer tylko że deklarują rzucanie wyjątku, więc jak nie mogę tego rzucania zmienić to przynajmniej nadal mogę gdzieś to sobie lambdować.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
PI
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 miesiące
  • Postów:2787
0
Shalom napisał(a):

@Pinek jw, skoro chcesz obsługiwać to od razu to czemu wyjątek a nie Optional?

@Shalom Chodzi mi o wytłumaczenie istnienia w JDK checked wyjątków, bo napisałeś wcześniej że w ogóle wszędzie są skopane ;) a raczej się dotychczasowych metod do tego nie zmieni. A ja osobiście zawsze rzucam RuntimeException jak już ;)

Shalom
To Jarek pisał a nie ja :P
PI
Faktycznie :D Obydwaj strzelacie postami po 100 dziennie :D
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:35 minut
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

Wyjątki checked istnieją bo kiedyś się to wydawało dobrym pomysłem. Ale ... jakoś ten dobry pomysł nie działa dobrze. 98 % (przyznaje, że z d**y liczba) obsługi wyjatków checked w programach Java to bzdurny rethrow albo jeszcze gorzej - połknięcie wyjątku.


jeden i pół terabajta powinno wystarczyć każdemu
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@Shalom: no faktycznie, jak na ironie to akurat dzisiaj chciałem monadę ale nie mogłem bo przy mapowaniu był checked exception. Ale na szczęście to bardzo rzadko się zdarza, ostatni raz taki problem miałem kilkaset dni temu :)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)