User Tools

Site Tools


Problem constructing authldap
laboratoare:exceptii
Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:exceptii [2019/01/06 17:19]
Laurentiu Stamate [Resurse]
laboratoare:exceptii [2019/11/30 19:55] (current)
Tudor Paraschivescu [Resurse]
Line 11: Line 11:
 De exemplu, în cadrul unui program care copiază un fişier, astfel de evenimente excepţionale pot fi: De exemplu, în cadrul unui program care copiază un fişier, astfel de evenimente excepţionale pot fi:
 * absenţa fişierului pe care vrem să-l copiem * absenţa fişierului pe care vrem să-l copiem
-* imposibilitatea de a-l citi din cauza permisiunilor insuficiente ​sau din cauza unei zone invalide de pe hard-disk+* imposibilitatea de a-l citi din cauza permisiunilor insuficiente
 * probleme cauzate de accesul concurent la fişier * probleme cauzate de accesul concurent la fişier
  
Line 25: Line 25:
 if (openResult == FILE_NOT_FOUND) { if (openResult == FILE_NOT_FOUND) {
     // handle error     // handle error
-} else if (openResult == INUFFICIENT_PERMISSIONS) {+} else if (openResult == INSUFFICIENT_PERMISSIONS) {
     // handle error     // handle error
 } else {// SUCCESS } else {// SUCCESS
Line 47: Line 47:
 } catch (FILE_NOT_FOUND) { } catch (FILE_NOT_FOUND) {
     // handle error     // handle error
-} catch (INUFFICIENT_PERMISSIONS) {+} catch (INSUFFICIENT_PERMISSIONS) {
     // handle error     // handle error
 } catch (DISK_ERROR) { } catch (DISK_ERROR) {
Line 60: Line 60:
 Când o eroare se produce într-o funcţie, aceasta creează un **obiect excepţie** şi îl pasează către ''​runtime system''​. Un astfel de obiect conţine informaţii despre situaţia apărută: Când o eroare se produce într-o funcţie, aceasta creează un **obiect excepţie** şi îl pasează către ''​runtime system''​. Un astfel de obiect conţine informaţii despre situaţia apărută:
 * **tipul** de excepţie * **tipul** de excepţie
-* **stiva de apeluri** (stack trace): punctul din program unde a intervenit excepţia, reprezentat sub forma lanţului de metode ​(obţinut prin invocarea succesivă a metodelor din alte metode) ​în care programul se află în acel moment+* **stiva de apeluri** (stack trace): punctul din program unde a intervenit excepţia, reprezentat sub forma lanţului de metode în care programul se află în acel moment
  
 Pasarea menţionată mai sus poartă numele de **aruncarea** (throwing) unei excepţii. ​ Pasarea menţionată mai sus poartă numele de **aruncarea** (throwing) unei excepţii. ​
Line 82: Line 82:
  
 În realitate, clasa ''​Exception''​ este părintele majorităţii claselor excepţie din Java. Enumerăm câteva excepţii standard: În realitate, clasa ''​Exception''​ este părintele majorităţii claselor excepţie din Java. Enumerăm câteva excepţii standard:
-* [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​IndexOutOfBoundsException.html|IndexOutOfBoundsException]]:​ este aruncată când un index asociat unei liste sau unui vector depăşeşte dimensiunea colecţiei respective. +* [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​IndexOutOfBoundsException.html|IndexOutOfBoundsException]]:​ este aruncată când un index asociat unei liste sau unui vector depăşeşte dimensiunea colecţiei respective. 
-* [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​NullPointerException.html|NullPointerException]]:​ este aruncată când se accesează un obiect neinstanţiat (''​null''​). +* [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​NullPointerException.html|NullPointerException]]:​ este aruncată când se accesează un obiect neinstanţiat (''​null''​). 
-* [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​util/​NoSuchElementException.html|NoSuchElementException]]:​ este aruncată când se apelează next pe un ''​Iterator''​ care nu mai conţine un element următor.+* [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​NoSuchElementException.html|NoSuchElementException]]:​ este aruncată când se apelează next pe un ''​Iterator''​ care nu mai conţine un element următor.
  
 În momentul în care se instanţiază un obiect-excepţie,​ în acesta se reţine întregul lanţ de apeluri de funcţii prin care s-a ajuns la instrucţiunea curentă. Această succesiune se numeşte **stack trace** şi se poate afişa prin apelul [[http://​docs.oracle.com/​javase/​1.4.2/​docs/​api/​java/​lang/​Throwable.html#​printStackTrace()|e.printStackTrace()]],​ unde ''​e''​ este obiectul excepţie. În momentul în care se instanţiază un obiect-excepţie,​ în acesta se reţine întregul lanţ de apeluri de funcţii prin care s-a ajuns la instrucţiunea curentă. Această succesiune se numeşte **stack trace** şi se poate afişa prin apelul [[http://​docs.oracle.com/​javase/​1.4.2/​docs/​api/​java/​lang/​Throwable.html#​printStackTrace()|e.printStackTrace()]],​ unde ''​e''​ este obiectul excepţie.
Line 117: Line 117:
 Funcţia ''​f''​ va arunca întotdeauna o excepţie (din cauza că ''​l''​ este mereu ''​null''​). Observaţi cu atenţie funcţia ''​catchFunction'':​ Funcţia ''​f''​ va arunca întotdeauna o excepţie (din cauza că ''​l''​ este mereu ''​null''​). Observaţi cu atenţie funcţia ''​catchFunction'':​
 * în interiorul său a fost definit un bloc ''​try'',​ în interiorul căruia se apelează ''​f''​. De obicei, pentru a **prinde** o excepţie, trebuie să specificăm o zonă în care aşteptăm ca excepţia să se producă (**guarded region**). Această zonă este introdusă prin ''​try''​. * în interiorul său a fost definit un bloc ''​try'',​ în interiorul căruia se apelează ''​f''​. De obicei, pentru a **prinde** o excepţie, trebuie să specificăm o zonă în care aşteptăm ca excepţia să se producă (**guarded region**). Această zonă este introdusă prin ''​try''​.
-* în continuare, avem blocul ''​catch''​ (''​Exception e''​). La producerea excepţiei, blocul ''​catch''​ corespunzător va fi executat. În cazul nostru se va afişa mesajul ''"​S-a generat o excepţie"''​.+* în continuare, avem blocul ''​catch''​ (''​Exception e''​). La producerea excepţiei, blocul ''​catch''​ corespunzător va fi executat. În cazul nostru se va afişa mesajul ''"​S-a generat o excepţie"''​. După aceea, programul va continua să ruleze normal în continuare.
  
 Observaţi un alt exemplu: Observaţi un alt exemplu:
  
 <code java> <code java>
-public void f() throws ​MyExceptionWeirdException ​+public void f() throws ​NullPointerExceptionEmptyListException ​
-    List<​String>​ l = null+    List<​String>​ l = generateList()
-                 +  
-    if (null == l+    if (== null
-        throw new MyException(); +        throw new NullPointerException(); 
- +  
-    throw new WeirdException("This exception never gets thrown"​);+    ​if (l.isEmpty()) 
 +        ​throw new EmptyListException();
 } }
 + 
 public void catchFunction() { public void catchFunction() {
     try {     try {
         f();         f();
-    } catch (MyException ​e) {+    } catch (NullPointerException ​e) {
         System.out.println("​Null Pointer Exception found!"​);​         System.out.println("​Null Pointer Exception found!"​);​
-    } catch (WeirdException ​e) { +    } catch (EmptyListException ​e) { 
-        System.out.println("​WeirdException ​found!"​);​+        System.out.println("​Empty List Exception ​found!"​);​
     }     }
 } }
 </​code>​ </​code>​
  
-În acest exemplu funcţia ''​f''​ a fost modificată astfel încât să arunce ​''​MyException''​. Observaţi faptul că în ''​catchFunction''​ avem două blocuri ''​catch''​. ​Cum excepţia aruncată de ''​f''​ este de tip ''​MyException'',​ numai primul ​bloc ''​catch''​ se va executa.+În acest exemplu funcţia ''​f''​ a fost modificată astfel încât să existe posibilitatea de a arunca ''​NullPointerException''​ sau ''​EmptyListException''​. Observaţi faptul că în ''​catchFunction''​ avem două blocuri ''​catch''​. ​În funcție de excepția aruncată de ''​f'',​ numai un singur ​bloc ''​catch''​ se va executa.
  
 Prin urmare: Prin urmare:
-* putem specifica **porţiuni** de cod pentru **tratarea** excepţiilor folosind blocurile ''​try''​ şi ''​catch''​ +* putem defini mai multe blocuri ​''​catch''​ pentru a implementa o tratare preferenţială a excepţiilor,​ în funcţie de tipul acestora 
-* putem defini **mai multe** blocuri catch pentru a implementa o tratare ​**preferenţială** a excepţiilor,​ în funcţie de tipul acestora+* în cazul aruncării unei excepții într-un bloc ''​try'',​ se va intra **într-un singur bloc** ''​catch''​ (cel aferent excepției aruncate)
  
 <note important>​ <note important>​
Line 204: Line 205:
 Nu toate excepţiile trebuie prinse cu ''​try-catch''​. Pentru a înțelege de ce, să analizăm clasificarea ​ excepţiilor:​ Nu toate excepţiile trebuie prinse cu ''​try-catch''​. Pentru a înțelege de ce, să analizăm clasificarea ​ excepţiilor:​
  
-{{ :​laboratoare:​exceptii:​tipurideexceptii.png?​nolink&​400 |Tipuri de excepţii}}+{{ :​laboratoare:​exceptii:​exceptions-hierarchy.png?​nolink&​500 |Tipuri de excepţii}}
  
-**Checked exceptions**,​ ce corespund clasei [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​Exception.html|Exception]]:​ +Clasa **[[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Throwable.html|Throwable]]**:​ 
-  * Acestea sunt excepţii pe care o aplicaţie bine scrisă ar trebui să le **prindă**,​ şi să permită **continuarea** rulării programului.+  * Superclasa tuturor erorilor și excepțiilor din Java. 
 +  * Doar obiectele ce extind această clasă pot fi aruncate de către JVM sau prin instrucțiunea ''​throw''​. 
 +  * Numai această clasă sau una dintre subclasele sale pot fi tipul de argument într-o clauză ''​catch''​. 
 + 
 +**Checked exceptions**,​ ce corespund clasei [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Exception.html|Exception]]:​ 
 +  * aplicaţie bine scrisă ar trebui să le **prindă**,​ şi să permită **continuarea** rulării programului.
   * Să luăm ca exemplu un program care cere utilizatorului un nume de fişier (pentru a-l deschide). În mod normal, utilizatorul va introduce un nume de fişier care există şi care poate fi deschis. Există insă posibilitatea ca utilizatorul să greşească,​ caz în care se va arunca o excepţie ''​FileNotFoundException''​.   * Să luăm ca exemplu un program care cere utilizatorului un nume de fişier (pentru a-l deschide). În mod normal, utilizatorul va introduce un nume de fişier care există şi care poate fi deschis. Există insă posibilitatea ca utilizatorul să greşească,​ caz în care se va arunca o excepţie ''​FileNotFoundException''​.
-  * Un program bine scris va prinde această excepţie, va afişa utilizatorului un mesaj de eroare, şi îi va permite ​acestuia (eventualsă reintroducă un nou nume de fişier.+  * Un program bine scris va prinde această excepţie, va afişa utilizatorului un mesaj de eroare, şi îi va permite eventual să reintroducă un nou nume de fişier.
  
-**Errors**, ce corespund clasei [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​Error.html|Error]]:​+**Errors**, ce corespund clasei [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Error.html|Error]]:​
   * Acestea definesc situaţii excepţionale declanşate de factori **externi** aplicaţiei,​ pe care aceasta nu le poate anticipa şi nu-şi poate reveni, dacă se produc.   * Acestea definesc situaţii excepţionale declanşate de factori **externi** aplicaţiei,​ pe care aceasta nu le poate anticipa şi nu-şi poate reveni, dacă se produc.
-  * Spre exemplu, ​tentativa ​de a citi un fişier care nu poate fi deschis din cauza unei defecţiuni hardware (sau eroare OS), va arunca ''​IOError''​. +  * Spre exemplu, ​alocarea unui obiect foarte mare (un vector cu milioane ​de elemente), poate arunca ''​OutOfMemoryError''​. 
-  * Aplicaţia poate încerca să prindă această ​excepţie, pentru a anunţa utilizatorul despre problema apărută; după această însă, programul va eşua (afişând eventual ''​stack trace''​).+  * Aplicaţia poate încerca să prindă această ​eroare, pentru a anunţa utilizatorul despre problema apărută; după această însă, programul va eşua (afişând eventual ''​stack trace''​).
  
-**Runtime Exceptions**,​ ce corespund clasei [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​RuntimeException.html|RuntimeException]]:​+**Runtime Exceptions**,​ ce corespund clasei [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​RuntimeException.html|RuntimeException]]:​
   * Ca şi erorile, acestea sunt condiţii excepţionale,​ însă spre **deosebire** de **erori**, ele sunt declanşate de factori **interni** aplicaţiei. Aplicaţia nu poate anticipa, şi nu îşi poate reveni dacă acestea sunt aruncate.   * Ca şi erorile, acestea sunt condiţii excepţionale,​ însă spre **deosebire** de **erori**, ele sunt declanşate de factori **interni** aplicaţiei. Aplicaţia nu poate anticipa, şi nu îşi poate reveni dacă acestea sunt aruncate.
   * **Runtime exceptions** sunt produse de diverse bug-uri de programare (erori de logică în aplicaţie, folosire necorespunzătoare a unui API, etc).   * **Runtime exceptions** sunt produse de diverse bug-uri de programare (erori de logică în aplicaţie, folosire necorespunzătoare a unui API, etc).
Line 224: Line 230:
 Excepţiile **checked** sunt cele **prinse** de blocurile ''​try-catch''​. Toate excepţiile sunt **checked** cu excepţia celor de tip **Error**, **RuntimeException** şi subclasele acestora, adica cele de tip **unchecked**. Excepţiile **checked** sunt cele **prinse** de blocurile ''​try-catch''​. Toate excepţiile sunt **checked** cu excepţia celor de tip **Error**, **RuntimeException** şi subclasele acestora, adica cele de tip **unchecked**.
  
-Excepţiile **error** nu trebuie (în mod obligatoriu) prinse folosind ''​try-catch''​. Opţional, programatorul poate alege să le prindă. 
  
-Excepţiile **runtime** nu trebuie ​(în mod obligatoriuprinse folosind ​''​try-catch''​. ​Ele sunt de tip **RuntimeException**. Aţi întâlnit deja exemple de excepţii runtime, în urma diferitelor neatenţii de programare: ''​NullPointerException'',​ ''​ArrayIndexOutOfBoundsException'',​ etc.+Nu este indicată prinderea excepţiilor **unchecked** (de tip [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​Error.html|Error]] sau [[http://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​RuntimeException.html|RuntimeException]]cu ''​try-catch''​. 
 </​note>​ </​note>​
  
Line 278: Line 284:
 } }
 </​code>​ </​code>​
 +</​note>​
 +
 +<note tip>
 +Din **Java 7**, a fost adăugată construcția ''​try-with-resources'',​ care ne permite să declarăm resursele într-un bloc de ''​try'',​ cu asigurarea că resursele vor fi închise după executarea acelui bloc. Resursele declarate trebuie să implementeze interfața [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​lang/​AutoCloseable.html|AutoCloseable]].
 +
 +<code java >
 +try (PrintWriter writer = new PrintWriter(file)) {
 +    writer.println("​Hello World"​);​
 +}
 +</​code>​
 +
 </​note>​ </​note>​
  
Line 294: Line 311:
  
 == Exerciţii == == Exerciţii ==
-  - **(2p)** ​ ​Scrieţi o metodă (scurtă) care să genereze [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​OutOfMemoryError.html|OutOfMemoryError]] şo alta care să genereze [[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​lang/​StackOverflowError.html|StackOverflowError]]. ​ Verificaţposibilitatea de a continua rularea ​după interceptarea acestei eroriComparaţrăspunsul cu posibilitatea de a realiza acelaşi lucru într-un limbaj compilat, ce rulează direct pe platforma gazdă (ca C)+  - **(2p)** ​Citițde la **stdin** ​linie de text și afișați-o la **stdout** folosind BufferedReader-ul definit în schelet. Nu uitați ​să afișați un mesaj sugestiv în cazul apariției unei excepții și să închidețresursa ​după terminarea folosirii acesteiaFolosițconstrucția ''​try-with-resources''​ sau ''​try-catch-finally''​
-  - **(2p)**  Definiţi o clasă care să implementeze operaţii pe numere **întregi**. Operaţiile vor arunca excepţii. ​Scrieţi clasa ''​Calculator'',​ ce conţine trei metode: +  - **(3p)**  Definiţi o clasă care să implementeze operaţii pe numere **double**. Operaţiile vor arunca excepţii. ​Clasa va trebui să implementeze interfața ​''​Calculator'',​ ce conţine trei metode: 
-    * ''​add'':​ primeşte ​doi întregi ​şi întoarce un **întreg** +    * ''​add'':​ primeşte ​două numere ​şi întoarce un ''​double''​ 
-    * ''​divide'':​ primeşte ​doi întregi ​şi întoarce un **întreg** +    * ''​divide'':​ primeşte ​două numere ​şi întoarce un ''​double''​ 
-    * ''​average'':​ primeşte o colecţie ce conţine obiecte ''​Integer'',​ şi întoarce media acestora ca un numar de tip **întreg**. Pentru calculul mediei, sunt folosite ​operaţiile ​''​add''​ şi ''​divide''​. +    * ''​average'':​ primeşte o colecţie ce conţine obiecte ''​double'',​ şi întoarce media acestora ca un numar de tip ''​double''​. Pentru calculul mediei, sunt folosite ​metodele ​''​add''​ şi ''​divide''​. 
-    * Definiţi ​următoarele excepţii şi îmbogăţiţi corespunzător definiţia metodei ​''​add''​: +    * Metodele pot arunca ​următoarele excepții (definite în interfața ''​Calculator''​):​ 
-    * ''​OverflowException'':​ este aruncată dacă suma celor doua numere depăşeşte ''​Integer.MAX_VALUE''​ +      * ''​NullParameterException'':​ este aruncată dacă vreunul din parametrii primiți este ''​null''​ 
-    * ''​UnderflowException'':​ este aruncată dacă suma celor doua numere ​este mai mică decat ''​Integer.MIN_VALUE''​ +      * ''​OverflowException'':​ este aruncată dacă suma a două numere ​egală cu ''​Double.POSITIVE_INFINITY''​ 
-    * Care este alegerea firească: excepţii **checked** sau **unchecked**?​ De ce? Consideraţi că, pentru un utilizator care doreşte efectuarea de operaţii aritmetice, **singurul** mecanism disponibil este cel oferit de clasa ''​Calculator''​. +      * ''​UnderflowException'':​ este aruncată dacă suma a două numere ​e egală cu ''​Double.NEGATIVE_INFINITY''​ 
-    * Evidenţiaţprin teste toate cazurile posibile care generează excepţii. +    * Completați metoda ''​main''​ din clasa ''​MainEx2'',​ evidențiind prin teste toate cazurile posibile care generează excepţii. 
-  - **(2p)** Demonstraţi într-un program execuţia blocului ''​finally''​ chiar şi în cazul unui ''​return''​ din metoda+  - **(1p)**  ​Care este alegerea firească ​pentru exercițiul trecut: excepţii **checked** sau **unchecked**?​ De ce? Consideraţi că, pentru un utilizator care doreşte efectuarea de operaţii aritmetice, **singurul** mecanism disponibil este cel oferit de clasa ''​Calculator''​. ​Discutațcu asistentul
-  - **(4p)** Dorim să implementăm un ''​Logger''​ pe baza pattern-ului Chain-of-responsibility,​ definit mai sus, pe care îl vom folosi să păstram un jurnal de evenimente ​unui program (vezi adaptarea în Referințe):​ +  - **(4p)** Dorim să implementăm un ''​Logger''​ pe baza pattern-ului Chain-of-responsibility,​ definit mai sus, pe care îl vom folosi să păstram un jurnal de evenimente ​al unui program (vezi adaptarea în Referințe):​ 
-    - **(1p)** Creați enumerația ''​LogLevel'',​ ce va acționa ca un [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​EnumSet.html|bitwise flag]], care va conține valorile - ''​None, Info, Debug, Warning, Error, FunctionalMessage,​ FunctionalError''​. Această enumerație va expune și o metodă statică ''​All()''​ care va întoarce o colecție de ''​EnumSet<​LogLevel>''​ în care vor fi toate valorile de mai sus. [[https://​www.geeksforgeeks.org/​enumset-class-java/​|Exemplu]] practic de folosire.+    - **(1p)** Creați enumerația ''​LogLevel'',​ ce va acționa ca un [[https://​docs.oracle.com/​javase/​8/​docs/​api/​java/​util/​EnumSet.html|bitwise flag]], care va conține valorile - ''​Info,​ Debug, Warning, Error, FunctionalMessage,​ FunctionalError''​. Această enumerație va expune și o metodă statică ''​all()''​ care va întoarce o colecție de ''​EnumSet<​LogLevel>''​ în care vor fi toate valorile de mai sus (Hint: ''​EnumSet.allOf()''​). [[https://​www.geeksforgeeks.org/​enumset-class-java/​|Exemplu]] practic de folosire.
     - **(1p)** Creați o clasă abstractă ''​LoggerBase'':​     - **(1p)** Creați o clasă abstractă ''​LoggerBase'':​
-      - va primi pe constructor un obiect de tip ''​EnumSet<​LogLevel>''​ care va defini pentru ce ''​LogLevel'' ​va afisa mesajul +      - va primi în constructor un obiect de tip ''​EnumSet<​LogLevel>''​ care va defini pentru ce nivele de log se va afisa mesajul 
-      - va expune o metodă publică ''​setNext''​ ce va primi un ''​LoggerBase'',​ va întoarce ​''​LoggerBase''​ și va seta următorul delegat din lista de responsabilitate+      - va păstra o referință către următorul ​''​LoggerBase'' ​la care se trimite ​mesajul 
 +      - va expune o metodă publică ''​setNext''​ ce va primi un ''​LoggerBase''​ și va seta următorul delegat din lista de responsabilitate
       - va defini o metodă abstractă protected ''​writeMessage''​ ce va primi mesajul care trebuie afișat       - va defini o metodă abstractă protected ''​writeMessage''​ ce va primi mesajul care trebuie afișat
-      - va expune o metodă publică ''​message''​ ce va primi mesajul care trebuie afișat și o severitate de tip ''​LogLevel''​. Dacă instanța de logger ​trebuie să afișeze mesajul pe baza colecției primite ​pe constructor,​ atunci se va apela metoda ''​writeMessage'' ​apoi se va pasa mesajul și severitatea către următorul delegat din lista de responsabilitate (setat prin apelul ''​setNext''​)+      - va expune o metodă publică ''​message''​ ce va primi mesajul care trebuie afișat și o severitate de tip ''​LogLevel''​. Dacă instanța de logger ​conține această severitate în colecția primite ​în constructor,​ atunci se va apela metoda ''​writeMessage''​. Apoi se vor pasa mesajul și severitatea către următorul delegat din lista de responsabilitate (dacă există unul)
     - **(2p)** Definiți clasele de mai jos care vor extinde ''​LoggerBase''​ și implementa metoda ''​writeMessage'':​     - **(2p)** Definiți clasele de mai jos care vor extinde ''​LoggerBase''​ și implementa metoda ''​writeMessage'':​
-      - ConsoleLogger - care va scrie toate tipurile de ''​LogLevel''​ și va prefixa mesajele cu ''​[Console] ''​+      - ConsoleLogger - care va scrie toate tipurile de ''​LogLevel'' ​(Hint: ''​all()''​) ​și va prefixa mesajele cu ''​[Console] ''​
       - EmailLogger - care va scrie doar tipurile ''​FunctionalMessage''​ și ''​FunctionalError''​ și va prefixa mesajele cu ''​[Email] ''​       - EmailLogger - care va scrie doar tipurile ''​FunctionalMessage''​ și ''​FunctionalError''​ și va prefixa mesajele cu ''​[Email] ''​
       - FileLogger - care va scrie doar tipurile ''​Warning''​ și ''​Error''​ și va prefixa mesajele cu ''​[File] ''​       - FileLogger - care va scrie doar tipurile ''​Warning''​ și ''​Error''​ și va prefixa mesajele cu ''​[File] ''​
-      - instanțiați obiectele ​în clasa ''​Test'' ​și explicați de ce obțineți rezultatul ​din schelet.+      - Hint: ''​EnumSet.of()''​ 
 +      - Completați cele 2 **TODO**-uri rămase ​în metoda ​''​main''​ din clasa ''​MainEx4''​.
  
 == Resurse == == Resurse ==
  
-* {{:laboratoare:​exceptii:​skel.zip|Schelet}} +* {{laboratoare:​exceptii:​skel-lab-exceptii.zip|Schelet}} 
-* {{:laboratoare:​exceptii:​lab9-sol.zip|Soluție}}+* {{laboratoare:​exceptii:​sol-lab-exceptii.zip|Soluție}}
 * <​html><​a class="​media mediafile mf_pdf"​ href="/​poo/​laboratoare/​exceptii?​do=export_pdf">​PDF laborator</​a></​html>​ * <​html><​a class="​media mediafile mf_pdf"​ href="/​poo/​laboratoare/​exceptii?​do=export_pdf">​PDF laborator</​a></​html>​
  
laboratoare/exceptii.1546787985.txt.gz · Last modified: 2019/01/06 17:19 by Laurentiu Stamate