SCJP 1/10: Flow Control, Exceptions, Assertions

96 views
Skip to first unread message

Jacek Pospychała

unread,
Sep 20, 2009, 5:40:04 AM9/20/09
to jug-p...@googlegroups.com
Cześć,
zgodnie z planem zapraszam na pierwsze spotkanie przygotowujące nas do SCJP.
Poruszana tematyka to: Flow Control, Exceptions, Assertions
Najpierw zobaczymy na co szczególnie kładą nacisk materiały do SCJP, a następnie
pobawimy się z zadaniami i zagadkami.
Zapowiada się niezła zabawa


Gdzie: Cognifide, al. Wielkopolska 4
Kiedy: poniedziałek 21.09, godzina 18:00 (tak, jutro!)


Zapraszam!


Jacek

Jacek Pospychała

unread,
Sep 22, 2009, 3:13:23 AM9/22/09
to jug-p...@googlegroups.com
hej,
nieobecnym opiszę po krótce jak nam się udało pierwsze spotkanie.
Przejrzenie rozdziału "Flow Control, Exceptions, Assertions" zajęło mi ok 1,5 godziny. Na spotkaniu zajęło nam prawie godzinę przewertowanie go jeszcze raz, skupiając się tylko na ciekawych rzeczach, a było na czym :-)

Za książką: "Don't get your hopes up about the exam questions being all nice and indented properly [...] anything that can be made more confusing, will be."
Dalej w wielu miejscach ostrzegają, by uważnie sprawdzić czy kod w zadaniu się w ogóle skompiluje, a dopiero następnie analyzować treść zadania. Wielokrotnie jedną z odpowiedzi jest "This code won't compile".

1. Konstrukcja "if":
- uważać na wielokrotnie zagnieżdżone if'y, oraz który else jest do którego if'a. Na ogół proste, robi się trudniejsze gdy kod jest nie wcięty albo podstępnie źle sformatowany.
- uważać na przypisania w miejscu instrukcji warunkowej. Jeśli przypisanie jest typu boolean, to się skompiluje; w innych przypadkach nie.

2. Konstrukcja "switch"
- uwaga na typ wyrażenia w instrukcji warunkowej. Może być tylko char, byte, short, int, enum. Nie long
- ciekawy kwiatek: (nie skompiluje się, gdyż 128 jest spoza zakresu byte)
byte i = 0;
switch (i) {
  case 128: ...
}
- uwaga na celowo błędne konstrukcje, np. pomijające słowo kluczowe case, lub dwukropki

switch (x) {
  case 0 {
  }
}

switch (x) {
  0: { ... }
  1: { ... }
}

- uważać by nie przegapić opcji "default"

3. Pętle i iteratory
- uwaga na niepoprawne konstrukcje, np. while (int x = 2) {...}
- for-each: typ zmiennej pętli musi się zgadzać z typem obiektu po którym iterujemy
- continue/break: muszą być wewnątrz pętli lub w switch (to się nie odnosi do podpisanych breaków/labeled break)
- prosty kawałek kodu na przemyślenie:

boolean isTrue = true;
outer:
for (int i=0; i<5;i++) {
  while (isTrue) {
    System.out.println("Hello");
    break outer;
  } // end of inner while loop
  System.out.println("Outer loop."); // won't print
} // end of outer for loop
Syste.out.println("Good-Bye");

Prints:
Hello
Good-Bye

outer:
for (int i=0; i<5;i++) {
  while (isTrue) {
    System.out.println("Hello");
    continue outer;
  } // end of inner while loop
  System.out.println("Outer loop."); // won't print
} // end of outer for loop
Syste.out.println("Good-Bye");


Prints:
Hello
Hello
Hello
Hello
Hello
Good-Bye

4. Wyjątki
- znać hierarchię typów Throwable, Error, Exception, RuntimeException
- znać kilka podstawowych typów wyjątków i umieć ocenić czy w podanym kodzie zostaną wyrzucone: ArrayIndexOutOfBounds, ClassCastException, IllegalArgumentException, NullPointerException, NumberFormatException, AssertionError, ExceptionInInitializerError, StackOverflowError, NoClassDefFoundError
- część z powyższych jest typowo wyrzucana tylko przez JVM a część przez programistę. umieć rozróżnić
- uważać na celowe błędy w konstrukcji ty/catch/finally, np. bezsensowne instrukcje wstrzelone gdzieś między klauzulami
- uwaga na kolejność deklarowania wyjątków w sekcjach catch: od bardziej szczegółowych do bardziej ogólnych, łatwo tu o błędy kompilatora
- umieć prześledzić czy sprawdzany wyjątek (checked exception) jest poprawnie obsłużony, np. w zadaniu z łańcuchem wywołań funkcji
- wiedzieć co się stanie jeśli nieobsłużony wyjątek zostanie wyrzucony w głównej metodzie programu
- ciekawy przykład jednej z osób z sali:
int doSth() {
try {
   return 10;
} finally {
   return 20;
}
}


5. Asercje
- budowa asercji: assert(wyrazenieWarunkowe):wyrazenie2  - :wyrazenie2 jest opcjonalne i zostanie doklejone do wyjątku w przypadku nie spełnienia asercji, np. assert(i >= 10):"i is less than 10";
- assert a różne wersje javy. Od javy 1.4, assert jest słowem kluczowym i użycie np. jako nazwa zmiennej kończy się błędem kompilacji
- włączanie/wyłączanie asercji: -ea, -enableassertions, -da, -disableassertions, -dsa (assertions for system library)
- selektywne włączanie/wyłączanie asercji: -ea:com.package.Foo (włączenie tylko dla klasy Foo), -ea:com.package... (dla pakietu package i jego podpakietów)
- nie używać asercji w metodach publicznych


Na końcu rozdziału jest przydatny 2-minute drill krótka ściąga z mniej więcej wszystkim co powyżej.

Następnie 15 zadań. Wcześniej szacowaliśmy po 30sec-1min na zadanie. Okazuje się że dobrze mieć do 4-5min na zadanie, na ogół trzeba dokładnie przeanalizować każdą opcję, np. wstawić każdą odpowiedź do przykładowego kawałku kodu i ocenić czy się skompiluje, lub przeanalizować każde ze zdań czy jest poprawne/nie. Często są też zadania typu "co wypisze dany program"...

Zdąrzyliśmy zrobić 5 zadań :-)

mam nadzieję że wszyscy się dobrze bawili. Moje wrażenie jest takie że do egzamu najlepiej podchodzić już z odrobiną doświadczenia w czytaniu i rozumieniu kodu. Niestety egzamin nie kładzie nacisku na typowe błędy programistyczne, a bardziej na znajomość działania kompilatora i wykrywanie problemów którymi w większości obecnie zajmują się IDE.
...chociaż może to dlatego że temat tego rozdziału nie był zbyt wysublimowany i tam się nie da popełnić większych błędów a zadania i tak muszą pokrywać cały materiał :-P


Następne spotkanie w następny poniedziałek. Szczegóły już w krótce!
Zapraszam!


Jacek


2009/9/20 Jacek Pospychała <jacek.po...@gmail.com>

Dawid Weiss

unread,
Sep 22, 2009, 3:30:51 AM9/22/09
to jug-p...@googlegroups.com
> - for-each: typ zmiennej pętli musi się zgadzać z typem obiektu po którym
> iterujemy

A dokladniej, to musi byc rzutowalny (assignable) z typu T dla
Iterable<T> po ktorym sie iteruje.

Dawid

Adam Dudczak

unread,
Sep 22, 2009, 3:54:37 AM9/22/09
to Poznań Java User Group
Jacku,

świetne podsumowanie! dzięki wielkie - postaram się następnym razem
dotrzeć, ale dzięki Tobie mogę być na bieżąco :)

pozdr. ad

Artur Kłopotek

unread,
Sep 22, 2009, 3:56:38 AM9/22/09
to jug-p...@googlegroups.com
> 1. Konstrukcja "if":
> ...

> - uważać na przypisania w miejscu instrukcji warunkowej. Jeśli przypisanie
> jest typu boolean, to się skompiluje; w innych przypadkach nie.

Oczywiście konstrukcje if / while mogą zawierać przypisania inne niż
boolean, o ile całe wyrażenie będzie typu boolean, np.:
if ((a=5) > 0) { ... }

Tak moim skromnym zdaniem, egzamin skupia się za bardzo na poprawności
syntaktycznej - innymi słowy wcielamy się w kompilator, musząc zwracać
uwagę np. na to, czy nie zapomniano dwukropka za etykietą case. Mały
ma to związek z byciem "dobrym" programistom, czy nawet wydajnym
programistą (kompilator javac - w przeciwieństwie np. do g++ - sam
wyłapie nam każdy brakujący średnik). Wyobraża sobie ktoś wrzucić
niepoprawny składniowo kod do repozytorium? Imo egzamin powinien
skupiać się bardziej na błędach logicznych / wynikających z braku
znajomości dokumentacji.

Pozdrawiam
Artur

Dawid Weiss

unread,
Sep 22, 2009, 4:20:18 AM9/22/09
to jug-p...@googlegroups.com
Niestety tak jest. Ma to pewne walory -- programista uważny patrzy na
to, co pisze, a nie tylko korzysta z pomocy kompilatora. Ja sam
spotkałem się parę razy w życiu z przypadkowymi błędami, których
kompilator nie wyłapie, bo są poprawne składniowo, lecz łudząco dobre:

float var = 0.4;
if (var > 0.5); {
System.out.println("var > 0.5");
}

Jak się człowiek skupi, to widać gdzie jest problem, ale taki kod się
normalnie kompiluje. Sam jednak również jestem przeciwny łapaniu na
tego typu konstrukcje, bo to nigdzie nie prowadzi.

Dawid

2009/9/22 Artur Kłopotek <a.klo...@gmail.com>:

Leszek Ciesielski

unread,
Sep 22, 2009, 4:31:53 AM9/22/09
to jug-p...@googlegroups.com
2009/9/22 Dawid Weiss <dawid...@cs.put.poznan.pl>:

>
> Niestety tak jest. Ma to pewne walory -- programista uważny patrzy na
> to, co pisze, a nie tylko korzysta z pomocy kompilatora. Ja sam
> spotkałem się parę razy w życiu z przypadkowymi błędami, których
> kompilator nie wyłapie, bo są poprawne składniowo, lecz łudząco dobre:
>
> float var = 0.4;
> if (var > 0.5); {
>  System.out.println("var > 0.5");
> }
>
> Jak się człowiek skupi, to widać gdzie jest problem, ale taki kod się
> normalnie kompiluje. Sam jednak również jestem przeciwny łapaniu na
> tego typu konstrukcje, bo to nigdzie nie prowadzi.
>

Mały wtręt ze światka .NET: javac nie wygeneruje ostrzeżenia w takiej sytuacji?

Jacek Białecki

unread,
Sep 22, 2009, 4:37:48 AM9/22/09
to jug-p...@googlegroups.com
W dniu 22 września 2009 10:31 użytkownik Leszek Ciesielski
<sko...@gmail.com> napisał:

>
>
> Mały wtręt ze światka .NET: javac nie wygeneruje ostrzeżenia w takiej sytuacji?
>

Ależ oczywiście, że wygeneruje... Wygeneruje "possible loss of
precision", wszak w kodzie występuje próba przypisania wartości "0.4",
która jest typu double na "węższy" typ float :-P

Pozdrawiam!

PS. no offfence - only kidding ;-)


--
yacoll

Optymiści wierzą, że świat stoi przed nimi otworem.
Pesymiści wiedzą, gdzie ma ten otwór.

Marcin Kłopotek

unread,
Sep 22, 2009, 4:41:13 AM9/22/09
to jug-p...@googlegroups.com
2009/9/22 Leszek Ciesielski <sko...@gmail.com>:

Javac niestety nie, ale każde szanujące się IDE już tak.

Artur Kłopotek

unread,
Sep 22, 2009, 4:43:27 AM9/22/09
to jug-p...@googlegroups.com
> Mały wtręt ze światka .NET: javac nie wygeneruje ostrzeżenia w takiej sytuacji?

Tutaj na szczęście z pomocą przychodzą takie narzędzie jak FindBugs:
http://findbugs.sourceforge.net/

Jacek Pospychała

unread,
Sep 22, 2009, 4:43:50 AM9/22/09
to jug-p...@googlegroups.com

2009/9/22 Marcin Kłopotek <marcin....@gmail.com>

> Mały wtręt ze światka .NET: javac nie wygeneruje ostrzeżenia w takiej sytuacji?
Javac niestety nie, ale każde szanujące się IDE już tak.


to zależy... np. w Eclipse to jest domyślnie wyłączone, ale po włączeniu (opcja "Empty statement" dla ciekawskich), owszem...


shot.PNG

Jacek Pospychała

unread,
Sep 22, 2009, 4:56:31 AM9/22/09
to jug-p...@googlegroups.com
2009/9/22 Jacek Pospychała <jacek.po...@gmail.com>


to zależy... np. w Eclipse to jest domyślnie wyłączone, ale po włączeniu (opcja "Empty statement" dla ciekawskich), owszem...


hehe, w załączniku pełna referencja różnych fajnych opcji...
może zamiast przygotowywać się do SCJP zrobimy sobie spotkanie, pt. jak wyeliminować głupie błędy?

najprostszy sposób na rozpowszenienie tych opcji w zespole to skonfigurować opcje ostrzeżeń/błędów specyficznie dla projektu - wówczas ustawienia zostaną zapisane w plikach <project>\.settings, a następnie wrzucić całość z projektem do CVS/SVN/whatever.
shot.PNG

Marcin Kłopotek

unread,
Sep 22, 2009, 5:00:21 AM9/22/09
to jug-p...@googlegroups.com
Poza tym raz na jakiś czas warto jednak przejechać projekt FindBugs'em
lub innym narzędziem do statycznej analizy kodu, naprawdę nie boli, a
można się wiele ciekawych rzeczy dowiedzieć. Taki ciekawy przykład:

private void doSth(File file) {
FileWriter writer;
try {
writer = new FileWriter(file);
/* some magic here */
} catch (IOException e) {
new RuntimeException(e);
} finally {
FileUtil.close(writer);
}
}


PS. Brat mnie uprzedził z FindBugsem gdy pisałem tego posta :)

Artur Kłopotek

unread,
Sep 22, 2009, 6:41:55 AM9/22/09
to jug-p...@googlegroups.com
W dniu 22 września 2009 11:00 użytkownik Marcin Kłopotek
<marcin....@gmail.com> napisał:

>
> Poza tym raz na jakiś czas warto jednak przejechać projekt FindBugs'em
> lub innym narzędziem do statycznej analizy kodu, naprawdę nie boli, a
> można się wiele ciekawych rzeczy dowiedzieć. Taki ciekawy przykład:
>
>        private void doSth(File file) {
>                FileWriter writer;
>                try     {
>                        writer = new FileWriter(file);
>                        /* some magic here */
>                } catch (IOException e) {
>                        new RuntimeException(e);
>                } finally {
>                        FileUtil.close(writer);
>                }
>        }
>

Ośmielę się zapytać - co jest ciekawego w tym przykładzie, poza tym,
że się on nie skompiluje? (w finally używana jest zmienna writer,
która może być niezainicjalizowana - wykryje to kompilator, nie
potrzeba FindBugs)

Marcin Kłopotek

unread,
Sep 22, 2009, 6:49:59 AM9/22/09
to jug-p...@googlegroups.com
2009/9/22 Artur Kłopotek <a.klo...@gmail.com>:

Braciszku, załóżmy że poprawiłeś błąd kompilacji. Mała podpowiedź,
spójrz na blok catch {...} Finbugs jednak się przyda w tym przypadku,
bo jak widać kompilator i Ty nie zauważaliście pomyłki ;)

Michał Garlicki

unread,
Sep 22, 2009, 6:53:01 AM9/22/09
to jug-p...@googlegroups.com
gdzieś się zapodział throw... ;)

pozdrawiam,
garlik

2009/9/22 Marcin Kłopotek <marcin....@gmail.com>:

Artur Kłopotek

unread,
Sep 22, 2009, 6:55:34 AM9/22/09
to jug-p...@googlegroups.com
> Braciszku, załóżmy że poprawiłeś błąd kompilacji. Mała podpowiedź,
> spójrz na blok catch {...}  Finbugs jednak się przyda w tym przypadku,
> bo jak widać kompilator i Ty nie zauważaliście pomyłki ;)

Napotkawszy błąd kompilacji, zaniechałem dalszej analizy ;-)

Dawid Weiss

unread,
Sep 22, 2009, 8:07:22 AM9/22/09
to jug-p...@googlegroups.com
> Napotkawszy błąd kompilacji, zaniechałem dalszej analizy ;-)

Niestety te pytania SUNa mają podobny charakter -- często jest zasłona
dymna, a błąd kryje się w innym miejscu. Ja zresztą nie neguję tego,
że dużo błędów da się wyłapać automatycznie (findbugs, czy jdt); po
prostu nie wszystkie się da, a czasem głupi błąd jest najtrudniejszy
do znalezienia.

Dawid

P.S. Do Leszka: .NET, a w zasadzie C# ma nowszą specyfikację i parę
rzeczy napisanych zostało dużo lepiej. Między innymi compound
assignments typu +=, -= itd. są dużo ładniejsze i lepiej zdefiniowane.
Java ciągnie się długo i wiele rzeczy narosło lub zostało nałożonych
na kompilator (klasy wewnętrzne, syntetyczne accesory) lub jako nieco
koślawe rozszerzenie (erasure w generykach).

Reply all
Reply to author
Forward
0 new messages