This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:static-final [2019/10/19 21:14] Adriana Draghici [Static și final] |
laboratoare:static-final [2019/10/23 12:19] (current) Radu Matei [Exerciții] |
||
---|---|---|---|
Line 79: | Line 79: | ||
} | } | ||
</code> | </code> | ||
- | In acest caz, numarul de obiecte create in memorie este unul foarte mare. Dintre acestea doar cel rezultat la final este util. Pentru a preveni alocarea nejustificata a obiectelor de tip String care reprezinta pasi intermediari in obtinerea sirului dorit putem alege sa folosim clasa StringBuilder creata special pentru a efectua operatii pe siruri de caractere. | + | În acest caz, numărul de obiecte create în memorie este unul foarte mare. Dintre acestea doar cel rezultat la final este util. Pentru a preveni alocarea nejustificată a obiectelor de tip String care reprezintă pași intermediari în obținerea șirului dorit putem alege să folosim clasa StringBuilder creată special pentru a efectua operații pe șiruri de caractere. |
<code java5> | <code java5> | ||
public static String concatenareCuClasaStringBuilder(){ | public static String concatenareCuClasaStringBuilder(){ | ||
Line 90: | Line 90: | ||
</code> | </code> | ||
- | Cuvantul cheie final poate fi folosit si in alt context decat cel prezentat anterior. De exemplu, aplicat unei clase impiedica o eventuala derivare a acestei clase prin mostenire. | + | Cuvântul cheie final poate fi folosit și în alt context decât cel prezentat anterior. De exemplu, aplicat unei clase împiedică o eventuală derivare a acestei clase prin moștenire. |
<code java5> | <code java5> | ||
final class ParentClass { | final class ParentClass { | ||
Line 100: | Line 100: | ||
</code> | </code> | ||
- | In mod similar, in cazul in care aplicam cuvantul cheie final unei metode, acest lucru impiedica o eventuala suprascriere a acelei metode | + | În mod similar, în cazul în care aplicăm cuvântul cheie final unei metode, acest lucru împiedică o eventuală suprascriere a acelei metode. |
<code java5> | <code java5> | ||
class ParentClass { | class ParentClass { | ||
Line 150: | Line 150: | ||
} | } | ||
</code> | </code> | ||
- | Pentru a observa utilitatea variabilelor statice, vom crea o clasa care tine un contor static ce numara cate instante a produs clasa in total. | + | Pentru a observa utilitatea variabilelor statice, vom crea o clasa care ține un contor static ce numără câte instanțe a produs clasa în total. |
<code java5> | <code java5> | ||
class ClassWithStatics { | class ClassWithStatics { | ||
Line 179: | Line 179: | ||
} | } | ||
</code> | </code> | ||
- | Desi am mentionat anterior faptul ca field-urile si metodele statice se acceseaza folosind sintaxa ''<NUME_CLASA>.<NUME_METODA/FIELD>'' acesta nu este singura abordare disponibila in libajul Java. Pentru a referi o entitate statica ne putem folosi si de o instanta a clasei in care se afla metoda/field-ul accesat. | + | Deși am menționat anterior faptul că field-urile și metodele statice se accesează folosind sintaxa ''<NUME_CLASA>.<NUME_METODA/FIELD>'' acesta nu este singura abordare disponibilă în libajul Java. Pentru a referi o entitate statică ne putem folosi și de o instanța a clasei în care se află metodă/field-ul accesat. |
- | <note important>In acest caz nu este relevant daca tipul obiectului folosit este diferit de cel al referintei in care e stocat(i.e. avem o referinta a clasei Animal care refera un obiect de tipul Dog). Pentru apelul unei metode statice se va lua in considerare numai tipul referintei, nu si cel al instantei pe care o refera</note> | + | <note important>În acest caz nu este relevant dacă tipul obiectului folosit este diferit de cel al referinței în care e stocat(i.e. avem o referință a clasei Animal care referă un obiect de tipul Dog). Pentru apelul unei metode statice se va lua în considerare numai tipul referinței, nu și cel al instanței pe care o referă</note> |
<code java5> | <code java5> | ||
class ClassWithStatics { | class ClassWithStatics { | ||
Line 201: | Line 201: | ||
} | } | ||
</code> | </code> | ||
- | <note warning>Desi putem accesa o entitate statica folosind o referinta, acest lucru este contraindicat. Field-urile si metodele statice apartin clasei si nu ar trebui sa fie in nici un fel dependente de existenta unei instante.</note> | + | <note warning>Deși putem accesa o entitate statică folosind o referință, acest lucru este contraindicat. Field-urile și metodele statice aparțin clasei și nu ar trebui să fie in nici un fel dependențe de existența unei instanțe.</note> |
- | Pentru a facilita o initializare facila a field-urilor statice pe care o clasa le detine, limbajul Java pune la dispozitie posibilitatea de a folosi blocuri statice de cod. Aceste blocuri de cod sunt executate atunci cand clasa in cauza este incarcata de catre masina virtuala de java. Incarcarea unei clase se face in momentul in care aceaste este referita pentru prima data in cod (se creaza o instanta, se apeleaza o metoda statica etc.) | + | Pentru a facilita o initializare facilă a field-urilor statice pe care o clasa le deține, limbajul Java pune la dispoziție posibilitatea de a folosi blocuri statice de cod. Aceste blocuri de cod sunt executate atunci când clasa în cauza este încărcată de către mașina virtuală de java. Încărcarea unei clase se face în momentul în care aceaste este referita pentru prima dată in cod (se crează o instanță, se apelează o metodă statică etc.) |
- | In consecinta, blocul static de cod se va executa intotdeauna inainte ca un obiect sa fie creat. | + | În consecință, blocul static de cod se va execută întotdeauna înainte că un obiect să fie creat. |
<code java5> | <code java5> | ||
Line 295: | Line 295: | ||
* o constantă MAGIC_NUMBER având orice valoare doriți | * o constantă MAGIC_NUMBER având orice valoare doriți | ||
* un String constant MAGIC_STRING, lung de minim 20 de caractere, generat random | * un String constant MAGIC_STRING, lung de minim 20 de caractere, generat random | ||
- | * un constructor care primește: un String numit ''firstName'', un String numit ''lastName'' și un int numit ''age'' | + | * un constructor care primește: un String numit ''name'' |
* o metodă ''getPassword()'' care va returna parola | * o metodă ''getPassword()'' care va returna parola | ||
- | * parola se construiește concatenand următoarele șiruri: | + | * parola se construiește concatenand următoarele șiruri: |
- | * șirul format din ultimele ''(age % 3)'' litere din firstName | + | |
* un șir random de lungime MAGIC_NUMBER, generat cu ''RandomStringGenerator'' și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING | * un șir random de lungime MAGIC_NUMBER, generat cu ''RandomStringGenerator'' și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING | ||
- | * și șirul format prin conversia la String a numărului (age + lungimea lui lastName). | + | * și șirul format prin conversia la String a lungimii lui name + un numar intreg generat random din intervalul [0,100] |
* Pentru subșiruri și alte metode utile consultați documentația clasei [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html | String]] | * Pentru subșiruri și alte metode utile consultați documentația clasei [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html | String]] | ||
- | - (**3p**) Modificati implementarea clasei PasswordMaker astfel incat sa respecte conceptul de **Singleton pattern** (sa permita instantierea unei singur obiect) | + | - (**3p**) Modificați implementarea clasei PasswordMaker astfel încât să respecte conceptul de **Singleton pattern** (să permită instanțierea unei singur obiect) |
- | * Implementati Singleton pattern folosind conceptul de Eager Initialization (singura instanta a clasei este creata la pornirea aplicatiei, indiferent daca este necesar sau nu) | + | * Pornind de la exemplul de Singleton din textul laboratorului implementați o versiune care urmează principiul de Eager Initialization (singura instanța a clasei este creată la pornirea aplicației, indiferent dacă este necesar sau nu) |
- | * Modificati implementarea anterioara urmand conceptul de Lazy Initialization (singura instanta a clasei este creata doar atunci cand este nevoie de ea) | + | * Implementați o versiune de Singleton în care variabila ''instance'' este inițializata într-un bloc static |
- | - (**4p**) Să se implementeze o clasă ''MyImmutableArray'' care sa contina: | + | * Adăugați un contor care să numere de câte ori a fost accesată metodă ''getInstance()''. E nevoie ca acest contor să fie static? |
- | * un field de ''ArrayList<Integer> immutableArray;'' neinitializat in prima faza | + | * //Tema de gândire:// Ce se va întâmplă dacă folosim conceptul de Singleton pattern într-un program paralelizat, care rulează pe mai multe linii de execuție (thread-uri). Ce probleme ar putea să apară? |
- | * un constructor care primeste un ArrayList<Integer> si copiaza toate elementele din acel array in ''immutableArray'' | + | - (**3p**) Să se implementeze o clasă ''MyImmutableArray'' care să conțină: |
- | * o metoda getArray implementata in asa fel incat field-ul ''immutableArray'' sa ramana immutable | + | * un field de ''ArrayList<Integer> immutableArray;'' neinitializat în primă faza |
- | - (**1p**) Testati clasa ''MyImmutableArray'' demonstrand faptul ca instantele acestei clase sunt imutabile | + | * un constructor care primește un ArrayList<Integer> și copiază toate elementele din acel array în ''immutableArray'' |
+ | * o metodă getArray implementată în așa fel încât field-ul ''immutableArray'' să rămână immutable | ||
+ | - (**1p**) Testați clasa ''MyImmutableArray'' demonstrând faptul că instanțele acestei clase sunt imutabile | ||
+ | == Resurse == | ||
+ | * {{:laboratoare:static-final:schelet_lab4.zip|Arhiva zip cu clasa RandomStringGenerator.java}} | ||