Throws i throw

0

1 pytnie co robi throws i throw? - czytalem ze throws deklaruje wyjatek a throw rzuca , tylko ze jak nie uzyjemy throw to tez nam rzuca wyjatek tutaj przyklad:

public class b {
void add() throws InterruptedException
{
	Thread.sleep(1000);
	
}
}

I tutaj throw sie nie stusuje , a i tak wyjatek jest rzucony , czyli throws robi to co throw bo przekazuje ten wyjatek gdzies dalej? I to tyle jesli chodzi o wyjatki kontrolowane, a co do niekontrolowanych , po co uzywac w nich w ogóle throws i throw przyklad:

public class b {
void add() 
{
	int [] tab = {1};
	System.out.println(tab[10]);
}
}

tutaj jak w mainie w try catchu wywolamy ta metode to i tak jak bedzie blad to go wylapie wiec po co to stosowac? Pozdrawiam

1

o_O

  1. throw powoduje rzucenie konkretnego wyjątku. W programie sprawdzasz sobie np. jakieś parametry i są niepoprawne więc możesz chcieć wysokoczyć gdzieś wyżej do obsługi błędu i wyświetlic userowi informacje że coś jest nie tak, więc rzucasz sobie wyjątek.
  2. throws oznacza że dana metoda rzuca checked exception, ale on nie musi być generowany w tejże metodzie. Może być rzucany przez kod którego w danej metodzie używasz. W twoim przypadku Thread.sleep() może rzucić wyjątek InterruptedException, więc siłą rzeczy ta twoja funkcja add też może go rzucić, skoro go nie złapałeś. Wyjątki są przekazywane "w górę" dopóki nie zostaną złapane.
  3. Wyjątki checked są widoczne, więc wiadomo że musisz jakoś je obsługiwać. Wyjątki runtime są niewidzialne, więc jeśli jesteś nieogarnięty to jakaś głupota może ci położyć aplikacje, bo nie pomyślałeś o tym że gdzieś leci wyjątek. Generalnie uważa się że wyjątki checked są słabe, bo często powodują zaśmiecenie kodu i trzeba je przerzucać przez pół systemu albo obłsuguje sie je "od razu" (więc tez można równie dobrze użyć Either czy Optional zamiast tego).
1
  1. try - catch - finally możesz stosować sobie kiedy chcesz. Nie ma obowiązku rzucania wyjątku w środku, czy tym bardziej deklarowania.
  2. W 1 wyjątek jest rzucany gdzieś w środku Thread::sleep. Ta metoda deklaruje że rzuca ten wyjątek więc albo go obsłużysz, albo zadeklarujesz że pozwalasz na propagację wyżej.
  3. Zadeklarować wyrzucenie wyjątku możesz zawsze. Nie implikuje to konieczności rzucenia wyjątku, ale wymusza jego obsłużenie. Dlatego jeżeli zrobisz funkcję z throws to nie musisz wcale nic z niej wyrzucać, ale jeżeli jej użyjesz to musisz w jakiś sposób ją obsłużyć, czy to przez try-catch, czy przez dodanie throws w metodzie która jej użyje.
0

@Ro3ert
0. NIE ODPOWIADAJ NA TEMAT W KOMENTARZACH!

  1. Nie bardzo rozumiem gdzie widzisz problem. Przecież Thread.sleep() może rzucić wyjątek! Zresztą możesz sobie zadeklarować throws costam a niczego nie rzucać. Nie wiem po co, ale możesz ;] Wtedy każdy korzystający z twojej metody będzie musiał obłsługiwać ten wyjątek-widmo, nawet jeśli on nigdy w rzeczywistości nie może zostać rzucony.
  2. Wyjątków unchecked nie trzeba nigdzie deklarować i tyle. Ale to nie znaczy że działają jakoś inaczej -> można je tak samo łapać i obsługiwać, inaczej to by było zupełnie bez sensu.
0

Dopiero zauwzylem ze Thread.sleep(1000); rzuca wyjatek(ma w sobie throw) i tutaj juz wiem jak to dziala (throws deklaruje checked wyjatki i rzucany jest throw ok i w try catchu jest obslugiwany) ale jak sie ma to do tego przykladu:

public class b {
void add() 
{
    int [] tab = {1};
    System.out.println(tab[10]);
}
}

przeciez tutaj nie ma throw, a i tak jak wywolalem go w mainie w try catchu to tam zostal obsluzony?

0

Ale przecież ArrayOutOfBounds jest RuntimeException, więc nie trzeba go deklarować bo nie jest checked. A try..catch obsługuje dowolny typ wyjątków.

0

ale nie mowie tu o throws bo wiem ze nie trzeba, tylko o throw o rzuceniu wyjatku i ta metoda nie ma throw przeciez, czyli (na moja logike) wyjatek nie moze byc rzucony, wiec nie powinien trafic do try catch?

0

o_O no ale kod który masz w tej metodzie może rzucić wyjątek! Czego ty tu nie rozumiesz? tab[X] może rzucać ArrayOutOfBoundsException, i rzuca w twoim przypadku, więc siłą rzeczy twoja funkcja add także może rzucić ten wyjątek (i rzuca!).

0

czyli to:

public class b {
void add() 
{
    int [] tab = {1};
    System.out.println(tab[10]);
}
}
public class glowna{
public static void main(String[] args)
{
b bClass = new b();
try{
bClass.add();
}catch(ArrayIndexOutOfBoudsException e)
{
System.out.println("blad");
}
}
}

To jesli chodzi o obsluge bledu to to samo co:

try{
 int [] tab = {1};
    System.out.println(tab[10]);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("blad"):
}

tak?

2

Tak.

0

kurcze to troche nie rozumiem po co sie uzywa w ogóle te throw , skoro w wyjatkach checked i tak jest tam throw, a w wyjatkach unchecked to i tak bedzie wywolywana metoda w try catch i tak jak w tym przypadku nie trzeba bylo uzywac tego throw? A jak moja metoda uzyje throw(np ArrayIndexOutOfBoundsException) i bedzie przekazana do innej metody w ktorej nie bedzie try catch , to ta metoda wystarczy ze bedzie miala throws? nie musi miec throw new ArrayIndexOutOfBoundsException() ? Bo jesli tak to widze tylko sens uzywania tego throw tylko wtedy jezeli miejsce w ktorej wywolujemy ta metode z tym mozliwym bledem nie ma try catcha i tylko przekazujemy , bo jak ma to i tak bedzie oblsluzony tak jak to ten program ktory wyslalem.

2

No nie rozumiesz. Sprawa prosta, są dwa przypadki:

  1. Wołasz metodę, która wewnątrz siebie rzuca wyjątek typu checked i teraz masz dwie opcje:
    a) Obsłużyć wyjątek, czyli zrobić bloki try... catch
    b) Oddelegować odpowiedzialność za obsłużenie wyjątku wyżej, czyli do deklaracji swojej metody (który wywołuje ową metodę z checked exceptionem) dodajesz throws
  2. Wołasz metodę, która wewnątrz siebie rzuca (może rzucać) wyjątek typu unchecked (czyli de facto 99% metod) i znowu są 2 opcje:
    a) Chcesz obsłużyć wyjątek, który przewidujesz że może się zdarzyć i robisz bloki try...catch (raczej nie catchuje się ArrayOutOfBounds czy też NullPointera)
    b) Nie chcesz obsługiwać ewentualnego wyjątku, więc nic nie robisz i jest gitara (niech wyżej się martwią czy złapią czy nie)
0

Nie widze w tej odpowiedzi kiedy uzywamy throw? Oraz czemu nie catchujemy arrayindex.. oraz nullpointer.. ?

1

NIe chciało Ci się przeczytać nawet jednego poradnika od początku do końca.. :-(

Więc niech kod przemówi:

http://www.99-bottles-of-beer.net/language-java-866.html

Weź sobie ten kawałek i poanalizuj jak działa. Do zobaczenia.

0

Czytalem, ale jedynie polskie kursy ktore wlasnie mi tak pomieszaly w glowie, bo uzywalem throw do wyjatkow unchecked , pokombinowalem i zrobilem te same programy bez uzycia throw (chyba tylko raz uzylem throw), niestety jeszcze z angielskim mam problem, wiem ze jest kluczowy w programowaniu wiec juz zaczalem sie go uczyc, ale jeszcze takie czytanie kursow angielskich to dla mnie meczarnia i jedna strone jak czytam to musze z 20 razy na google tlumacz wchodzic ; / moze jak bede robil coraz trudniejsze zadanie moze zrozumiem , ostatnie pytanie , czy jezeli klasa rzuca wyjatek i wywoluje np ta klase w metodzie x, ale nie chcĘ jej obsluzyc w x to wystarczy ze uzyje throws w metodzie x i ten wyjatek leci dalej?

3

Odpowiedź na pytanie. Tak.
Ale może jeszcze raz poradnik.

  1. Do obsługi wyjątków jest tylko i wyłacznie try i catch i throw.
    throw - służy do rzucenia wyjątku
    catch do złapania, a try pokazuje gdzie się zaczyna sekcja gdzie łapiemy.
    Tu jeszcze wchodzi sprawa, że typ wyjątku w catch musi pasować od tego co poleciało żeby się złapał.

  2. Natomiast dodatkowo w Javie są tzw. checkeck exceptions. Przy czym nie wszystkie exceptions sa checked.
    (np. NullPointerException nie jest checked).
    Co to znaczy checked exception. To taki Exception, że kompilator Javy sprawdzi czy gdzieś jest catch tego Exceptiona,
    jak nie jest nigdzie łapany - to znaczy, że ktoś zapomniał i trzeba mu przypomnieć (wywalając błąd w kompilacji).

  3. Jak kompilator sprawdza?
    ano szuka czy jest catch, który pasuje do tego co leci w throw .
    Z tym, że czasami chcemy powiedzieć : ok obiecuję - złapię ten wyjątek tylko nie w tej metodzie.
    Do tego służy klauzula throws. Mówi, że ta metoda przekazuje (potencjalnie dalej wyjątek danego typu).
    Co oznacza, że ktokolwiek wywołuje tą metodę będzie sprawdzany czy robi catch.
    Dodatkowo to oznacza, że kompilator już się nie czepia tego, że w tej metodzie nie ma catch - bo wie, że sprawdzenie będzie na zewnątrz.
    (te throws można propagować - kolejna metoda może deklarować, że przekazjue dalej i dalej (aż do main :-) ).

  4. Po czym poznać wyjątek Checked ? Po tym, że nie dziedziczy z RuntimeException ani z Error.
    (czyli domyślnie są checked).

  5. Ogólnie checked exception (ideologicznie) wprowadzasz po to, żeby podkreślić, że twoja metoda oprócz standardowego rezultatu może się wywalić, bo ktoś np. podał złe argumenty i zmuszasz aby korzystający ten błąd jakoś obsłużył. (bo to jego poniekąd wina).
    Runtimowe exceptiony to ideologicznie te, na które wywołujący nie ma wpływu (bo np. rozleciała się baza danych).
    czyli metoda typu myRepository.getUserFromDB(int userID)
    może deklarować throws NoSuchUserException (checked) (bo ktoś podał ID użytkownika nieistniejącego).
    I wtedy wywołujący musi to obsłuzyć - jak dostanie wyjątek to np. pokaże jakiś komunikat, pozwoli uzytkownikowi wklepać inne ID i wywoła jeszcze raz.
    Tym razem może się uda :-)

Niezależnie ta sama metoda może rzucać RuntimeException (np. DBDisconnectedException). Tego drugie nie deklaruje się w throws ... bo i tak jak się baza rozłączyła to pupa zbita i nic nie zrobisz.

6*. żeby ci namieszać - ogólnie w nowych programach w Javie (od Java 8) najlepiej nie wprowadzać własnych checked exceptions

0

znowu wracam do tego nieszczesnego dla mnie tematu, jesli chodzi o wyjatki unchecked to kiedy w nich stosowac throw?(bo poki co to nie widze sensu uzywania tego throw(oprocz swoich wlasnych wyjatkow)) bo i tak w metodach ktore moga wywolac wyjatek checked jest uzyte throw, a wyjatkach unchecked , wystarczy w miejscu tam gdzie jest ta wywolywana metoda(ta ktora moze wywolac wyjatek unchecked) wstawic try catch to i tak obsluzy ten blad i nie trzeba uzywac throw(w tej metodzie co generuje unchecked)

1 użytkowników online, w tym zalogowanych: 0, gości: 1