background image

1

JTO

1

JTP: Wyjątki

Dr. Piotr Kosiuczenko

JTP

Dr Piotr Kosiuczenko

2

Błędy i Wyjątki

„

Programy zawierają błędy – im więcej linii kodu, tym 

prawdopodobieństwo wystąpienia błędu w kodzie jest 

większe. 

„

Typizacja pozwala na wykrycie części z nich, podobnie 

testowanie, ale nie wszystkich.

„

Część błędów w kodzie zostaje ujawniona dopiero w czasie 

wykonania programu i wtedy trzeba coś z nim zrobić. 

„

Z drugiej strony, użytkownik może wywołać metodę w 

niewłaściwy sposób i też wymaga zaradzenia.

„

W jawie rozróżnia  się błędy (ang. Error) i wyjątki (ang. 
Exception). 

„

Oba są podklasami Throwable.

JTP

Dr Piotr Kosiuczenko

3

Throwable

„

Gdy coś jest nie tak, np. program próbuje przeczytać wartość

atrybuty obiektu null, wtedy jest rzucany obiekt klasy
Throwable.

„

Rzucenie takiego obiektu może prowadzić albo do przerwania 

wykonania programu, albo może być odpowiednio potraktowane.

try { . . .  //execute method(); 
} catch (ErrorOrException e) { 

. . . //do something about it

} finally {

. . . //do whatever

JTP

Dr Piotr Kosiuczenko

4

Wyjątki

„

Rzucenie obiektu z klasy Throwable sygnalizuje pewną

anomalię.

„

Mechanizm wyjątków stosuje  się do zaradzania pewnym 
sytuacjom. 

„

Mechanizm błędów stosuje  się do informowania o tym, ze 
wystąpił błąd, z którego program nie może usunąć. 

JTP

Dr Piotr Kosiuczenko

5

Throwable: Bledy i Wyjątki

„

Error, czyli błąd, jest podklasą
Throwable.

„

Błąd oznacza poważny problem.

„

Błędy nie powinny być łapane. 

„

W rezultacie metoda rzucająca błąd nie 

musi deklarować go w klauzuli throws.

Throwable
Throwable
(String message)

Error

Exception

Assertion
Error

IOError

JTP

Dr Piotr Kosiuczenko

6

Wyjątki

„

Obiekty klasy Exception i jej podklas wskazują

na warunki, które mogą być odpowiednio 

potraktowane.

„

Wtedy taki wyjątek jest łapany i odpowiednia 

procedura, jeśli jest przewidziana, zostaje 

wykonana. 

Exception

IOException

ClassNotFound
Exception

MalFormed
URLException

EOFException

CloneNotSupported
Exception

Runtime
Exception

Interrupted
IOException

background image

2

JTP

Dr Piotr Kosiuczenko

7

Sprawdzane Wyjątki

„

Są dwa rodzaje wyjątków: sprawdzane i nie 

(ang. checked i unchecked exceptions). 

„

Sprawdzane wyjątki muszą być albo deklarowane 

w sygnaturze metody, albo łapane i obsługiwane 

wewnątrz niej. 

Exception

RunTime
Exception

IOException

ClassNotFound
Exception

CloneNotSupported
Exception

MalFormed
URLException

EOFException

Interrupted
IOException

JTP

Dr Piotr Kosiuczenko

8

Wyjątki

„

Wyjątki są mechanizmem przekazania kontroli i informacji z 
pewnego punktu w programie do kodu obsługi wyjątków.

try { 

. . .  //execute method(); 

} catch (ErrorOrException e) { 

. . . //do something about it

} finally {

. . . //do whatever

JTP

Dr Piotr Kosiuczenko

9

Wyjątki: Przykład 

try { 

System.out.println(“What’s your name?”); 
String name = console.readLine();
System.out.println(“Hello, “ + name + “!”);

} catch (IOException e) { 

e.printStackTrace();

System.exit(1);

Tu może być

rzucony 

wyjątek.

Tu jest on 

łapany.

A tu jest on 

obsługiwany.

JTP

Dr Piotr Kosiuczenko

10

Deklaracja Wyjątku

public void ask() throws IOExceptio { 

System.out.println(“What’s your name?”); 
String name = console.readLine();
System.out.println(“Hello, “ + name + “!”);

Deklaracja wyjątku w 

sygnaturze metody

Nie ma 

klauzul try i 

catch.

IOExceptio musi być obsłużony przez metodę wywołującą lub 

zadeklarowany w jej sygnaturze.

JTP

Dr Piotr Kosiuczenko

11

Wyjątki Czasu Wykonania

„

Wyjątki czasu wykonania nie muszą być

deklarowane w sygnaturze metody.  

„

Jeśli jednak metoda może rzucić innego rodzaju 

wyjątek, to ten wyjątek musi być zadeklarowany 

w jej sygnaturze. 

IllegalArgument
Exception

IllegalState
Exception

Runtime
Exception

IllegalState
Exception

Exception

IOException

ClassNotFound
Exception

CloneNotSupported
Exception

JTP

Dr Piotr Kosiuczenko

12

Deklaracja Wyjątku

public void credit(int amount) { 

if(amount < 0)

throw new IllegalArgumentException(“Over limit!”);

balance = balance – amount;

Deklaracja wyjątku 

nie jest potrzebna.

Nie ma 

klauzul try i 

catch.

Ten wyjątek może być albo obsłużony przez metodę wywołującą, 
albo przekazany dalej.

Wiadomość o 

bledzie.

background image

3

JTP

Dr Piotr Kosiuczenko

13

Deklaracja Wyjątku

public void

transfer(BankAccount target, 

double

amount) {

this

.debit(amount);

target.credit(amount);

}

Te instrukcje mogą

rzucać wyjątki. 

Metoda wywołana przez inną metodę może rzucić wyjątek. 

Co z nimi zrobić?

JTP

Dr Piotr Kosiuczenko

14

Obsługa Wyjątków 

public void

transfer(BankAccount target, 

double

amount) {

final double

oldBalanceThis = 

this

.

balance

;

final double

oldBalanceTarget = target.

balance

;

try

this

.debit(amount);

target.credit(amount);

catch

(IllegalArgumentException e) {

this

.

balance

= oldBalanceThis;

target.

balance

= oldBalanceTarget;

}

}

Zapisujemy wartość atrybutów.

Chcemy przywrócić stan sprzed rzucenia wyjątku.

Wykonujemy procedurę.  

W razie rzucenia 

wyjątku przywracamy 

wartość atrybutom 

sprzed wykonania 

procedury. 

JTP

Dr Piotr Kosiuczenko

15

Finally

try { . . .  //execute method(); 

} catch (ExceptionX e) { 

. . . //do something about it

} catch (ExceptionY e) { 

. . . //do something about it

} finally {

. . . //do whatever

Jest wykonywane 

niezależnie od tego, 

czy wyjątek zostanie 

rzucony.

Będzie wykonana
pierwsza klauzula 

catch, która złapie 

rzucony wyjątek.

A tu jest on 

obsługiwany.

JTP

Dr Piotr Kosiuczenko

16

Dziedziczenie: Co będzie wynikiem kompilacji?

public class

C {

public void

m() {

}

}

public class

D

extends

C {

public void

m() 

throws

IOException {

}

}

public class

C {

public void

m()   

throws

IOException {

}

}

public class

extends

C {

public void

m() {

}

}

Wynikiem będzie 

komunikat o błędzie 

kompilacji.

Wynikiem będzie powstanie 

klas binarnych.

JTP

Dr Piotr Kosiuczenko

17

Wyjątki a Dziedziczenie

Podklasa musi zachowywać kontrakt nadklasy. W przypadku dziedziczenia metoda 

w podklasie może rzucać tylko takie sprawdzane wyjątki, które są deklarowane w 

nadklasie. 

class

Parent {

public void

m() 

throws

IOException {

//. . .

}

}

class

Child1 

extends

Parent {

public void

m() {

//. . .

}

}

import

java.io.IOException;

class

Child2 

extends

Parent {

public void

m() 

throws

InterruptedIOException {

//. . .

}

OK, nie rzuca 

sprawdzanych 

wyjątków.

OK, rzuca wyjątek będący 
szczególnym przypadkiem 

wyjątku w nadklasie.

JTP

Dr Piotr Kosiuczenko

18

Pytanie: Co będzie wynikiem wykonania metody 

n

public void

m() {

try

{

System.

out

.println(

"m throws rune time exception e."

);

throw new

RuntimeException();

}  

catch

(RuntimeException e){

System.

out

.println(

"m handles e."

);

throw

e;

}

finally

{

System.

out

.println(

"m executes its finally-part."

);

}

}

public void

n() {

try

{

System.

out

.println(

"n calls m."

);

m(); 

catch

(RuntimeException e){

System.

out

.println(

"n handles e."

);

}

finally

{

System.

out

.println(

"n executes its finally-part."

);

}

}

background image

4

JTP

Dr Piotr Kosiuczenko

19

Odpowiedz

n calls m.
m throws rune time exception e.
m handles e.
m executes its finally-part.
n handles e.
n executes its finally-part.

JTO

20

JTP: Klonowanie

Dr. Piotr Kosiuczenko

JTP

Dr Piotr Kosiuczenko

21

Klonowanie

„

Jeśli klasa implementuje interfejs Cloneable, to jest 

możliwe klonowanie za pomocą standardowej metody.

„

Klasa Object zawiera metodę protected Object
clone().

„

Metoda ta zwraca wyjątek, jeśli obiekt, na którym została 

wykonana, należy do klasy, która nie implementuje 

interfejsu Cloneable. 

„

Jeśli obiekt należy do klasy implementującej Clonable, to 

metoda ta zwraca nowy obiekt, którego atrybuty są

identyczne z atrybutami klonowanego obiektu.

„

W przypadku tablicy i wektora zwracana/y jest nowa 

tablica/nowy wektor, których elementami są elementy 

klonowanej tablicy/wektora. 

JTP

Dr Piotr Kosiuczenko

22

Klonowanie

„

clone() może być przedefiniowana w podklasach a jej dostępność

rozszerzona do publicznej:

public

Object clone () 

throws

CloneNotSupportedException { 

return super

.clone(); 

}

„

Co będzie wynikiem klonowania obiektu a1?

„

Czasem głębsze klony są potrzebne.

a1 : A

b1 : B

lb

JTP

Dr Piotr Kosiuczenko

23

Klonowanie

Czasem głębsze klony są potrzebne:

public class

implements

Cloneable {

private

B b;

public

Object clone() 

throws

CloneNotSupportedException {

A x = (A)

this

.clone(); 

if

(

this

.b != 

null

)  

x.b = (B)b.clone();

return

x;

JTP

Dr Piotr Kosiuczenko

25

Klonowanie

„

Co  się stanie gdy metoda clone() zostanie wykonana w 

następującym przypadku? 

public class

Child

extends

Parent {

public

Object clone () 

throws

CloneNotSupportedException {

Child x = (Child)

super

.clone(); 

Rzucony zostanie 

wyjątek, bo metoda 

sklonuje

this

jako 

obiekt klasy Parent.

background image

5

JTO

26

JTP: Identyczność – Porównywanie Obiektów

Dr. Piotr Kosiuczenko

JTP

Dr Piotr Kosiuczenko

27

Identyczność: equals()

„

Klasa Object zawiera metodę:

public boolean equals(Object obj)

„

Metoda ta służy do porównywania obiektów.

„

W przypadku klasy Object porównywane są obiekty tak, jak w 

przypadku ==, tj. this.equals(Object o) zwraca true, 

jeśli this jest tym samym obiektem co o. 

„

W ogólności jednak metoda ta ma służyć do porównywania 

stanów obiektów, w szczególności ich atrybutów. 

JTP

Dr Piotr Kosiuczenko

28

Identyczność: equals

Metoda equals(Object o) powinna spełniać następujące 

warunki dla x i y różnych od null (porównaj Java API):

„

zwrotno

ś

ć

: x.equals(x) zwraca true.

„

symetria

:    x.equals(y) zwraca true wtw y.equals(x)

zwraca true.

„

przechodnio

ś

ć

: jeśli x.equals(y) zwraca true i jeśli 

y.equals(z) zwraca true, to x.equals(z) zwraca true.

„

zgodno

ś

ć

: wielokrotne wywołanie x.equals(y) stale zwraca 

true lub stale false.

„

x.equals(null) zwraca false. 

JTP

Dr Piotr Kosiuczenko

29

Identyczność: Implementacja

class

Point {

public boolean

equals(Point o) {

return

(

this

.

x

== o.

x

&& 

this

.

y

== o.

y

);

}
//...

}

public boolean

equals(Object o) {

if

(!(o

instanceof

Point)) 

return false

;

else return

(

this

.

x

== ((Point)o).

x

&& 

this

.

y

== ((Point)o).

y

);

}

przeładowanie – uwaga 

na tę metodę, bo może 

być niespodziewanie 

użyta.

przedefiniowanie

Uwaga na dziedziczenie!

JTP

Dr Piotr Kosiuczenko

30

Identyczność: Implementacja z Uwzgl. Dziedziczenia

public class

ColourPoint

extends

Point {

int

c

public

ColourPoint(

double

nx, 

double

ny, 

int

nc) {

...

}

public boolean

equals(Object o) {

if

(!(o

instanceof

ColourPoint)) 

return false

;

return

(

super

.equals(o) && 

this

.

c

== ((ColourPoint)o).

c

);

}

public static void

main(String[] args) {

ColourPoint cp1 = 

new

ColourPoint(1, 2, 7);

ColourPoint cp2 = 

new

ColourPoint(1, 2, 7);

Point p1 = 

new

Point(1, 2);

System.

out

.println(cp1.equals(cp2));

System.

out

.println(cp2.equals(cp1));

System.

out

.println(cp1.equals(p1));

System.

out

.println(p1.equals(cp2));

}

}

Uwaga na 

przeładowanie.

Zobacz poprzedni 

slajd.

Niesymetryczna

relacja.

JTP

Dr Piotr Kosiuczenko

31

Identycznosc: Impl. z Uwzgl. Dziedziczenia 

public class

Point {

...

public boolean

equals(Object o) {

if

(!(

this

.getClass() == o.getClass())) 

return false

;

else return

(

this

.

x

== ((Point)o).

x

&&   

this

.

y

== ((Point)o).

y

);

}

}

public class

ColourPoint

extends

Point {

int

c

...

public boolean

equals(Object o) {

if

(!(

this

.getClass() == o.getClass()))   

return false

;

else return

(

super

.equals(o) && 

this

.

c

== ((ColourPoint)o).

c

);

}

}

symetryczne warunki

symetryczny warunek

background image

6

JTP

Dr Piotr Kosiuczenko

33

Identycznosc vs. Klonowanie

„

Zasadniczo powinno być tak, że jeśli o1 jest klonem o2

dokonanym na tym samym poziomie co aktualna klasa o2, to 
o1.equals(o2) zwraca true.
(równoważnie o.equals(o.clone()) zwraca true) 

„

Co więcej: o.clone().getClass() == o.getClass().

JTO

34

JTP: Rodzaje w Javie (Java Generics)

Dr. Piotr Kosiuczenko

JTP

Dr Piotr Kosiuczenko

35

Rodzaje

„

Rodzaje zapewniają bezpieczeństwo związane z typami. 

„

W czasie kompilacji jest możliwość sprawdzenia poprawności 

danej formuły pod względem typów:
Vector v Vector<T>; 

Vector<Integer> v = new Vector<Integer>();
v.add(10);  
v.add(“TEN"); 

„

JTP

Dr Piotr Kosiuczenko

36

Klasy Rodzajowe

„

Niektóre typy danych i klasy mogą być zaimplementowane 

niezależnie od konkretnego typu swoich atrybutów i metod, tzn. 

mogą posiadać parametry będące typami (polimorfizm). 

„

Vector<T> - kiedy taki parametr zostaje zastąpiony 

konkretnym typem, taka klasa może być skompilowana. 

„

Klasa posiada parametry, których wartościami są typy jest 

nazywana parametryczną lub rodzajową. 

JTP

Dr Piotr Kosiuczenko

37

Klasy Rodzajowe

public class

Pair<T> {

private

first

;

private

second

;

public

Pair(T f, T s) {

first

= f;

second

= s;

}

public

Pair() {

first

= new T();

second

= new T();

}

public

T getFirst() {

return

first

;

}

public

T getSecond() {

return

second

;

}

public void

setFirst(T f) {

first

= f;

}

public void

setSecond(T s) {

second

= s;

}

Parametrem musi być

klasa - nie może być

typ prymitywnym. 

metoda 

parametryczna

Niepoprawna

deklaracja

JTP

Dr Piotr Kosiuczenko

38

Klasy Rodzajowe

public

String toString() {

return

"["

first

.toString() + 

", "

second

.toString() + 

"]"

;

}

public boolean

equals(Object o) {

if

(!(

this

.getClass() == o.getClass())) 

return

false

;

return

(

this

.

first

.equals(((Pair)o).

first

) && 

this

.

second

.equals(((Pair)o).

second

));

}

}

Wiemy, że o jest tej 

samej klasy, co 

this

Parametr musi 

być klasą. 

background image

7

JTP

Dr Piotr Kosiuczenko

39

Dlaczego Klasy Rodzajowe? Impl. bez rodzajów

static void

swapAll(Collection c) {  

for

(Object el : c) {  

T t = ((Pair)el).getFirst();
((Pair)el).setFirst(((Pair)el).getSecond());
((Pair)el).setSecond(t);

}

Collection c = new Vector();
c.add(new Object());
c.swapAll;

spowoduje bląd w 

czasie wykonania 

musimy 

dopasować typ 

JTP

Dr Piotr Kosiuczenko

40

Dlaczego Klasy Rodzajowe?

static

<T> 

void

swap(Collection<Pair<T>> c) {  

for

(Pair<T> el : c) {  

T t = el.getFirst();
el.setFirst(el.getSecond());
el.setSecond(t);

Collection c = new Vector<Pair<Integer>>();
c.add(new Object());
c.swapAll;

implementacja z 

rodzajami 

spowoduje  błąd w 

czasie kompilacji

JTP

Dr Piotr Kosiuczenko

41

Konstruktory

„

Niektóre typy danych i klasy mogą być zaimplementowane 

niezależnie od konkretnego typu swoich atrybutów i metod, tzn. 

mogą posiadać parametry będące typami.
Pair<Object> p = 

new

Pair<Object>(

null

null

);

„

W konstruktorach parametry nie mogą być deklarowane:
T o = new T();
Pair<T> p = new Pair<T>();
T[] a = new T[5];

„

Możliwa jest jednak automatyczna konwersja typów:
Pair<Integer> ip = 

new

Pair<Integer>(3, 5)

Jeśli T jest parametrem, to 

deklaracje te spowodują

błąd w czasie kompilacji.

JTP

Dr Piotr Kosiuczenko

42

Konstruktory

„

Czasem jest konieczne ograniczenie parametrów:
class RestrictedPair<T extends Color> {

... 

}

JTP

Dr Piotr Kosiuczenko

43

Konstruktory

„

Czasem jest konieczne powiązanie parametrow:

„

public class

MyVector<S

extends

Comparable> 

extends

Vector

„

public class

MyVector<S

extends

Comparable> 

extends

Vector<T>

„

public class

MyVector<S

extends

Comparable<?>> 

extends

Vector<S>

Niepoprawne, mimo że 

daje  się skompilować. 

użycie białej karty 

JTP

Dr Piotr Kosiuczenko

44

Konstruktory

„

Deklaracja metody rodzajowej z nowym parametrem T:

public static

<T> T genericM(T[] a) 

„

Wywołanie metody z aktualnym parametrem:
Object s = MyVector.<String>genericM(a);

konkretny typ 

background image

8

JTP

Dr Piotr Kosiuczenko

45

Kowariancja i Kontrawariancja

„

Zalozmy, że klasa Dog rozszerza klasę Animal.

„

Czy następujący kod jest poprawny?
Vector<Dog> dogs = new Vector<Dog>();
Vector<Animal> animals = dogs;

„

Vector<Dog> nie może być traktowane jako podklasa 
Vector<Animal> (tj. nie ma tzw. kowariancji.)

problem z wkładaniem 

obiektow klasy Animal

do wektora 

zawierającego tylko psy.

JTP

Dr Piotr Kosiuczenko

46

Rodzaje: Literatura Dodatkowa

„

Java Tutorial: 

http://java.sun.com/docs/books/tutorial/java/generics/in

dex.html