40
Wybrane elementy języka Java Paweł Zdziarski

Wybrane elementy języka Java

Embed Size (px)

DESCRIPTION

Wybrane elementy języka Java. Paweł Zdziarski. Wyjątki Reflection Tworzenie i zarządzanie obiektami Garbage Collector i finalize() Nowe elementy Javy 1.5 Typy sparametryzowane Covariant return types „ autoboxing ” Pętla w stylu foreach Bezpieczne ( type-safe ) enumeracje - PowerPoint PPT Presentation

Citation preview

Page 1: Wybrane elementy języka Java

Wybrane elementy języka Java

Paweł Zdziarski

Page 2: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 3: Wybrane elementy języka Java

Wyjątki

• Obsługa błędów semantycznych (runtime) w sposób efektywniejszy niż zwracanie kodu błędu metody

• Podnoszenie wyjątku

– Wywołanie metody podnoszącej wyjątek (throws)

– Explicite: klauzulą throw

Page 4: Wybrane elementy języka Java

Obsługa wyjątków

• Wyjątki są zgodnie z definicją języka precise – zoptymalizowana implementacja może wykonać część instrukcji naprzód, ale w przypadku zgłoszenia wyjątku musi zadbać o to, żeby w widocznym stanie wykonania (user-visible state) wyliczone były dokładnie te wyrażenia, które wystąpiły przed wyrażeniem podnoszącym wyjątek

• Znajdowana jest klauzula catch bloku try-catch dynamicznie zawierającego generujące wyjątek wyrażenie

Page 5: Wybrane elementy języka Java

Obsługa wyjątków• Jaki będzie rezultat wykonania

try{ try { throw new Exception1(); } catch(Exception1 e){

System.out.println("Wewnetrzny catch: ” +e.toString()); throw new Exception2();

} finally {throw new Exception3();} }catch (Exception e)

{System.out.println("Zewnetrzny catch: ” +e.toString());}

•Blok try-catch-finally ma jeden atrybut – propagowany dalej wyjątek. Zgodnie z definicją języka, wewnętrzny blok w tym przykładzie będzie propagował wyjątek klasy Exception3, a więcWewnetrzny catch: mypackage18.Application1$Exception1Zewnetrzny catch: mypackage18.Application1$Exception3

Page 6: Wybrane elementy języka Java

Przyczyny powstania wyjątku

• Błąd wykonania JVM – wyjątek zgłaszany synchronicznie– Operacja niezgodna z semantyką języka (np. java.lang.ArithmeticException )

– Błąd ładowania/linkowania programu ( NoClassDefFound )– Brak zasobu ( OutOfMemoryError, NoRouteToHostException )

• Jawne użycie klauzuli throw

•Wyjątek podnoszony asynchronicznie–Może wystąpić potencjalnie w dowolnym punkcie wykonania bieżącego wątku–Inny wątek wywołuje stop()–Wewnętrzny błąd JVM ( VirtualMachineError )

Page 7: Wybrane elementy języka Java

Hierarchia wyjątków

• checked (podklasy Exception nie będące RuntimeException) – muszą być wyspecyfikowane w klauzuli throws metody lub konstruktora; kompilator wymusza implementowanie obsługi takich wyjątków

• Unchecked – kompilator nie wymusza na programiście obsługi (ani deklaracji throws)– RuntimeException (np. ArithmeticException, NullPointerException) - kompilator nie ma możliwości posłużenia się zaawansowanymi technikami dowodzenia poprawności programów i nie może przez to stwierdzić, czy dany ciąg instrukcji może wygenerować taki wyjątek lub nie

– Error (np. OutOfMemoryError extends VirtualMachineError) – mamy do czynienia z „nienormalnym” (abnormal) stanem JVM

Page 8: Wybrane elementy języka Java

Error jest osobną, dziedziczącą po Throwable klasą – dzięki temu wszystkie wyjątki, które da się jakoś obsłużyć, można „potraktować” konstrukcją catch (Exception e)

OutOfMemoryError

ThreadDeath VirtualMachineError

Throwable

Error

NullPointerException

RuntimeException

Exception

MyExceptionIOException

IllegalArgumentException

ArithmeticException

SQLException

Page 9: Wybrane elementy języka Java

• Wyjątki

• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 10: Wybrane elementy języka Java

Pakiet java.lang.reflect

• Dostęp do obiektów reprezentujących konstrukcje samego języka• Obiekt Class (pakiet java.lang) reprezentuje załadowaną postać

binarną klasy; użycie:public static Class forName(String className) throws ClassNotFoundException

• Method reprezentuje metodę klasy lub interfejsuClass c = Class.forName(nazwaKlasy); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString());

• Analogiczne użycie obiektów klas Field, Constructor • Interfejs Member implementowany przez Field, Constructor,

Class i Method; udostępnia metodę getModifiers()

Page 11: Wybrane elementy języka Java

• Wyjątki• Reflection

• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 12: Wybrane elementy języka Java

Konstruktory

• W kodzie konstruktora pierwsza instrukcja może, opcjonalnie, być explicite wywołaniem konstruktora. Wpp domyślnie super() jest pierwszą instrukcją kodu konstruktora

• Explicite wywołania konstruktora– this(<lista_argumentow>)– super(<lista_argumentow>)– <wyrazenie>.super()

Page 13: Wybrane elementy języka Java

Wyrazenie.super()

• Tzw. kwalifikowane wywołanie konstruktora nadklasy. Przykład ze specyfikacji języka:

class Outer {

class Inner{ }}

class ChildOfInner extends Outer.Inner {

ChildOfInner() { (new Outer()).super(); }

}

Page 14: Wybrane elementy języka Java

Jak wykonywana jest konstrukcja wyrazenie.super() ?

• Rozważamy konstrukcję class O { class S {}}

class C extends O.S { C() { wyrazenie.super(argumenty);

ciag_pozostalych_instrukcji_konstruktora }}• wyrazenie jest wyliczane. Jeśli jego wartością jest null, wywołanie konstruktora

nadklasy kończy się wyjątkiem NullPointerException• Niech O będzie klasą bezpośrednią otaczającą statycznie (leksykalnie) klasę (C), w której

konstruktorze wystąpiła konstrukcja wyrazenie.super • Jeśli wartością wyrazenia nie jest obiekt klasy O ani podklasy klasy O, generowany jest

błąd kompilatora• Wyrażenia argumenty są wyliczane, od lewej do prawej• Konstruktor jest wywoływany

Page 15: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami

• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 16: Wybrane elementy języka Java

GC i finalization

• Środowisko uruchomieniowe Javy utrzymuje tablicę referencji do obiektów.

– Referencja jest usuwana, gdy obiekt przestaje być widoczny

– Jawne przypisanie null do zmiennej

• Gdy nie ma więcej referencji do obiektu,

– Finalization: użycie System.runFinalization() wywoła finalize() dla wszystkich obiektów czekających na postprzątanie

– Garbage collection: użycie System.gc() jawnie uruchamia GC

Page 17: Wybrane elementy języka Java

Osiągalność referencji

• Wyznaczanie zbioru referencji nieosiągalnych (unreachable) dla żadnego z wątków programu

• Jeśli wszystkie referencje do obiektu pochodzą z obiektów nieosiągalnych, sam obiekt jest nieosiągalny

• Uwaga: dodatkowe warunki jeśli używamy JNI

Page 18: Wybrane elementy języka Java

finalization

• finalize() zaimplementowana w Object (jako pusta metoda), programista może ją przesłonić

public class ProcessFile {protected void finalize() throws Throwable {try {file.close();}finally {super.finalize();}}

• (ciekawostka) w J2ME: brak metod związanych z garbage collection; jawne przypisanie null może zasugerować GC możliwość posprzątania obiektu

• „Reference Objects and Garbage Collection”, artykuł na stronie http://developer.java.sun.com/developer/technicalArticles/ALT/RefObj/

Page 19: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 20: Wybrane elementy języka Java

interface Action<E extends Exception> {void run() throws E;}

class AccessController {public static <E extends Exception>void exec(Action<E> action) throws E {

action.run();}

}

public class Main { public static void main(String[] args) { try {

AccessController.exec ( new Action<FileNotFoundException>() {

public void run() throws FileNotFoundException { someFile.delete(); }

} // new Action ... ); // AccessController.exec()}// koniec bloku try

catch (FileNotFoundException e) { } } // koniec metody main()} // koniec class Main

Page 21: Wybrane elementy języka Java

Typy sparametryzowane i JVM

• Programy używające generics są tłumaczone do bytecode’u Javy, wykonywanego przez JVM

• Proces nazywany erasure polega na mapowaniu typów generycznych do typów niesparametryzowanych

• Niech |T| oznacza erasure typu T, zachodzą wtedy m.in.

– |T <T1,...,Tn>| = |T|

– |T[]| = |T|[]

• Dokładny opis mechanizmu erasure, tłumaczenia metod i wyrażeń w „Adding Generics to the Java Programming Language: Participant Draft Specification”, dostępnym np. ze strony java.sun.com

Page 22: Wybrane elementy języka Java

Typy sparametryzowane i tablice

• Bez generics tablice mają następującą własność:

Tablica referencji nadtypu jest nadtypem tablicy referencji podtypu

• Wynika stąd np. to, że Object[] jest nadtypem String[]• Możemy dzięki temu m.in. napisać

Object[] objArr = new String[10];• Brak analogicznej własności w przypadku typów sparametryzowanych

LinkedList<Object> objList = new LinkedList<String>();

daje błąd kompilacji

Page 23: Wybrane elementy języka Java

Dynamiczna informacja o typie i array store check

• Tablice w Javie zawsze posiadają dynamiczną informację o typie przechowywanych w nich obiektów

• W czasie wykonywania operacji na tablicach wykonywany jest tzw. array store check, który może spowodować zgłoszenie ArrayStoreException

Object objArr = new String[10];

objArr[0] = new Object();

kompiluje się, ale w czasie wykonania zgłaszą wyjątek

• Programista może zakładać, że tablica zawiera elementy tego samego typu (albo podtypów tego typu)

• Store check nie jest w ogóle wykonywany w przypadku kolekcji typów sparametryzowanych, bo poniższy kod

LinkedList<Object> objList = new LinkedList<String>();

w ogóle się nie skompiluje

Page 24: Wybrane elementy języka Java

Typy sparametryzowane i tablice

• Tablice typów sparametryzowanych nie są dopuszczalne ze względów bezpieczeństwa

class Box<T> {final T x;Box(T x) { this.x = x;}}

Box<String>[] niebezpiecznaTablica = new Box<String>[3];Object[] tablicaObiektow = niebezpiecznaTablica;tablicaObiektow[0] = new Box<Integer>(3); /* błąd nie znajdowany przez tzw. array store check */

String s = niebezpiecznaTablica[0].x; // BOOM!

Page 25: Wybrane elementy języka Java

Typy sparametryzowane i rzutowanie

• Kompilator „nie zna” typu sparametryzowanego przed uruchomieniem programu

• zadanie utrzymania poprawności rzutowań do typu parametrycznego należy do programisty

static Integer foo() {Double d = new Double(1.0);return (Integer) d;}

• Powyższy kod nie kompiluje się z błędem inconvertible types (znaleziono Double, oczekiwano Integer)

Page 26: Wybrane elementy języka Java

Typy sparametryzowane i rzutowanie

• Powyższy program nie generuje ostrzeżeń kompilatora i wykonuje się dając...1.0!!!

• Dla przypomnieniaclass Number extends Objectclass Integer extends Numberclass Double extends Number

• Kompilator „zauważyłby” błąd przy rzutowaniu, jeśli w kodzie funkcji foo() napisalibyśmy po prostu return d;

• Kompilator nie generuje błędu, jeśli napiszemy return (T) d;

public class BadCast {static <T> T foo() {Double d = new Double( 1.0 );return ( T ) d;}

public static void main( String[] args ) {System.out.println( BadCast.<Integer>foo() ); } }

Page 27: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 28: Wybrane elementy języka Java

Covariant return types

• Do wersji 1.4 języka przesłaniająca implementowaną w nadklasie metoda podklasy musiała mieć identyczną sygnaturę – w szczególności, zwracany typ

• Poniższy kod nie kompiluje się w JRE 1.4.1_02class Fruit implements Cloneable {Fruit copy() throws CloneNotSupportedException { return

(Fruit) clone();}}class Apple extends Fruit implements Cloneable {Apple copy() throws CloneNotSupportedException { return

(Apple) clone();}}• Wywołując clone() na obiekcie Apple dostajemy obiekt nadklasy

Fruit i musimy niepotrzebnie rzutować w dół do Apple• Java 1.5 dopuszcza taką konstrukcję

Page 29: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 30: Wybrane elementy języka Java

System typów i autoboxing

• Typy proste (primitives) i referencyjne (obiekty)

• Czasem konstrukcja wymaga użycia typu referencyjnego:

– Jako typu parametryzującego szablon

– Jako obiektów kolekcji np. List

• Konieczne rzutowania

list.add(new Integer(1));

int i = ((Integer)list.get(0)).intValue();• Autoboxing / autounboxing robi to automatycznie

Integer integer = new Integer(1);

integer += 1;

Page 31: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 32: Wybrane elementy języka Java

Iterowanie po elementach kolekcji

• Dotychczas (Java 1.4) używamy konstrukcji typupublic void drawAll (Collection c) { Iterator itr = c.iterator();while (itr.hasNext()) {

((Shape)itr.next()).draw();}

}

• Używając typów parametrycznych, możemy zaoszczędzić sobie kodowania kilku rzutowań

public void drawAll (Collection<Shape> c) { Iterator<Shape> itr = c.iterator();

while (itr.hasNext()) {itr.next().draw();

}}

Page 33: Wybrane elementy języka Java

Pętla „foreach” + generics

• Nowa dopuszczalna postać pętli „for”

public void drawAll(Collection<Shape> c) { for (Shape s:c)

s.draw();}

• Rozwijane automatycznie do kodu

for (Iterator<Shape> $i = c.iterator(); $i.hasNext();) {Shape s = $i.next();

s.draw();}

Page 34: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 35: Wybrane elementy języka Java

Bezpieczne (type-safe) typy wyliczeniowe

• Dotychczas

class Movement {public static final int UP = 0;public static final int LEFT = 1;public static final int DOWN = 2;

public static final int RIGHT = 3;}

• Wywołanie metody oczekującej parametru takiego typu wyliczeniowego z parametrem np. 5 nie wygeneruje błędu kompilacji

• Nowa konstrukcja „enum”

class Movement {public enum Direction {up, left, down, right}

}

Page 36: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import– Metody ze zmienną liczbą parametrów

Page 37: Wybrane elementy języka Java

Statyczne „import”

• Po użyciu

import static java.lang.Math.*;

możemy pisać po prostu

int i = abs(-1);

zamiast kwalifikować dodatkowo nazwą pakietu

int i = Math.abs(-1);

• Potencjalne błędy kompilacji w przypadku powstającej w ten sposób dwuznaczności nazw

Page 38: Wybrane elementy języka Java

• Wyjątki• Reflection• Tworzenie i zarządzanie obiektami• Garbage Collector i finalize()• Nowe elementy Javy 1.5

– Typy sparametryzowane

– Covariant return types

– „autoboxing”

– Pętla w stylu foreach

– Bezpieczne (type-safe) enumeracje

– Statyczne import

– Metody ze zmienną liczbą parametrów

Page 39: Wybrane elementy języka Java

Zmienna liczba argumentów

public static int sum(int args...) {

int sum = 0;

for (int x : args ) /* użycie wcześniej przedstawianej konstrukcji „foreach” */

{sum += x; }

return sum;

}

Page 40: Wybrane elementy języka Java

Literatura i URLs

• Wprowadzenie do użycia Generics

http://developer.java.sun.com/developer/technicalArticles/releases/generics/

• Artykuł o tablicach typów sparametryzowanych

http://www.langer.camelot.de/Articles/Java/JavaGenerics/ArraysInJavaGenerics.htm

• The Java Language Specification, dostępna z java.sun.com