Java | |
---|---|
Clasa de limba | limbaj de programare multi-paradigmă , limbaj JVM și software |
Aparut in | 1995 |
Autor | James Gosling și Sun Microsystems |
Dezvoltator | Sun Microsystems și Oracle |
Extensie de fișier | .java, .class, .jar, .jadsau.jmod |
Eliberare | Java SE 18.0.2.1 ( 18 august 2022 ) |
A fost influențat | C++ , C , Ada , Simula 67 , Smalltalk , Objective-C , Object Pascal , Oberon , Eiffel , Modula-3 , Mesa , Simula , C# , UCSD Pascal , wrapper , Funcție variabilă , adnotare Java , Nicklaus Wirth , Patrick Naughton [d] și foreach |
Licență | GNU GPL [1] |
Site-ul web | oracle.com/ru/java/ |
Fișiere media la Wikimedia Commons |
Java [aprox. 1] este un limbaj de programare orientat pe obiecte puternic tipizat , dezvoltat de Sun Microsystems (dobândit mai târziu de Oracle ). Dezvoltarea este condusă de o comunitate organizată prin Procesul Comunităţii Java ; limbajul și tehnologiile de bază care îl implementează sunt distribuite sub licența GPL . Drepturile privind mărcile comerciale sunt deținute de Oracle Corporation .
Aplicațiile Java sunt de obicei traduse în bytecode special , astfel încât să poată rula pe orice arhitectură de computer pentru care există o implementare a Java Virtual Machine . Data oficială de lansare este 23 mai 1995. Ocupă locul înalt în clasamentele de popularitate a limbajului de programare (locul 2 în clasamentele IEEE Spectrum (2020) [2] și TIOBE (2021) [3] ).
Limbajul a fost inițial numit Oak ("Oak"), dezvoltat de James Gosling pentru programarea dispozitivelor electronice de larg consum. Deoarece o limbă cu acest nume exista deja, Oak a fost redenumit Java [4] . Numit după marca de cafea Java, care, la rândul său, a primit numele insulei cu același nume ( Java ), așa că emblema oficială a limbii arată o ceașcă de cafea fierbinte. Există o altă versiune a originii numelui limbii, asociată cu o aluzie la o mașină de cafea ca exemplu de dispozitiv de uz casnic pentru programare, pe care limba a fost creată inițial. În conformitate cu etimologia, în literatura în limba rusă de la sfârșitul secolului al XX-lea până în primii ani ai secolului XXI, numele limbii a fost adesea tradus ca Java și nu transcris.
Ca urmare a proiectului, lumea a văzut un dispozitiv fundamental nou, computerul personal de buzunar Star7 [5] , care a fost înaintea timpului său cu peste 10 ani, dar din cauza costului ridicat de 50 de dolari, nu a putut revoluționa. lumea tehnologiei și a fost uitat.
Dispozitivul Star7 nu a fost popular, spre deosebire de limbajul de programare Java și mediul său. Următoarea etapă din viața limbii a fost dezvoltarea televiziunii interactive. În 1994, a devenit clar că televiziunea interactivă a fost o greșeală.
De la mijlocul anilor 1990, limbajul a devenit utilizat pe scară largă pentru scrierea de aplicații client și software de server . În același timp, tehnologia applet-urilor Java , aplicații grafice Java încorporate în pagini web, a câștigat o oarecare popularitate; Odată cu apariția capacităților de pagini web dinamice în anii 2000, tehnologia a devenit mai puțin utilizată.
Dezvoltarea web folosește Spring Framework ; utilitarul Javadoc este folosit pentru documentare .
Programele Java sunt traduse în bytecode Java , care este executat de Java Virtual Machine (JVM), un program care procesează cod de octet și transmite instrucțiuni hardware-ului ca interpret .
Avantajul acestui mod de executare a programelor este independența completă a bytecode-ului față de sistemul de operare și hardware , ceea ce vă permite să rulați aplicații Java pe orice dispozitiv pentru care există o mașină virtuală corespunzătoare. O altă caracteristică importantă a tehnologiei Java este un sistem de securitate flexibil, în care execuția programului este complet controlată de mașina virtuală. Orice operațiune care depășește permisiunile stabilite de program (cum ar fi încercarea de acces neautorizat la date sau conectarea la un alt computer) provoacă o întrerupere imediată.
Adesea, dezavantajele conceptului de mașină virtuală includ degradarea performanței. O serie de îmbunătățiri au crescut ușor viteza programelor Java:
Potrivit site-ului shootout.alioth.debian.org, pentru șapte sarcini diferite, timpul de execuție în Java este în medie de o jumătate și jumătate până la două ori mai mare decât pentru C/C ++, în unele cazuri Java este mai rapid, iar în în unele cazuri este de 7 ori mai lent [6] . Pe de altă parte, pentru majoritatea dintre ele, consumul de memorie al unei mașini Java a fost de 10 până la 30 de ori mai mare decât cel al unui program C/C++. De remarcat este și un studiu realizat de Google , conform căruia există o performanță semnificativ mai scăzută și un consum mai mare de memorie în cazurile de testare în Java comparativ cu programe similare în C++ [7] [8] [9] .
Ideile din spatele conceptului și diversele implementări ale mediului de mașină virtuală Java au inspirat mulți entuziaști să extindă lista de limbi care ar putea fi folosite pentru a crea programe care rulează pe o mașină virtuală [10] . Aceste idei sunt exprimate și în specificația Common Language Infrastructure ( CLI ) care a stat la baza platformei .NET de la Microsoft .
Dezvoltarea Java a început în 1990, prima versiune oficială - Java 1.0 - a fost lansată abia pe 21 ianuarie 1996.
A doua versiune a fost lansată pe 19 februarie 1997 [11] .
Data lansării 8 decembrie 1998 [12] . Loc de joacă cu nume de cod. În acest caz, există confuzie. Au fost publicate cărți, de exemplu, Beginning Java 2 de Ivor Horton (mar 1999), de fapt pe J2SE 1.2 (numit anterior Java 2). Cu toate acestea, până astăzi sunt publicate astfel de cărți, de exemplu: H. M. Deitel, P. J. Deitel, S. I. Santry. Tehnologii de programare Java 2. Aplicații distribuite (2011).
Într-un moment în care se știe că Java 2 a fost înlocuit din punct de vedere istoric de versiunile ulterioare, astfel de titluri de cărți sunt înșelătoare în ceea ce privește versiunea de Java despre care sunt scrise de fapt. Dacă J2SE 1.2 este considerat a fi Java 2, dar autorii cărților Java 2 acceptă JDK 7, acest lucru duce la o confuzie completă.
Data lansării 8 mai 2000. Nume de cod Kestrel.
Data lansării 6 februarie 2002. Nume de cod Merlin.
Specificația Java 5.0 a fost lansată pe 30 septembrie 2004, cu numele de cod Tiger. De la această versiune, indexarea oficială a fost schimbată, în loc de Java 1.5, este mai corect să apelezi Java 5.0. Indexarea internă a Sun rămâne aceeași - 1.x. Modificările minore sunt acum incluse fără modificarea indexării, pentru aceasta se folosește cuvântul „Actualizare” sau litera „u”, de exemplu, Java Development Kit 5.0 Update 22. Se presupune că actualizările pot include atât remedieri de erori, cât și mici completări la API, JVM.
În această versiune, dezvoltatorii au făcut o serie de completări fundamentale la limbaj:
Versiunea a fost lansată pe 11 decembrie 2006, cu numele de cod Mustang. Indexarea oficială a fost modificată - în loc de versiunea 6.0 așteptată, versiunea este listată ca 6. Modificări minore, ca în Java 5.0, sunt făcute actualizărilor obișnuite ale versiunii, de exemplu, Java Standard Edition Development Kit 6 Update 27. Următoarele modificări au fost facute:
Data lansării 8 octombrie 2013.
JavaFX 2.2 este inclus în actualizarea Java SE 7 6 [15] . Din versiunea 11, modulul este livrat separat de JDK [16] .
Data lansării 10 octombrie 2013. Codename Micro Edition.
Versiunea a fost lansată pe 28 iulie 2011, cu numele de cod Dolphin [17] . Versiunea finală a Java Standard Edition 7 nu a inclus toate modificările planificate anterior. Conform planului de dezvoltare (planul „B”) [18] , includerea inovațiilor va fi împărțită în două părți: Java Standard Edition 7 (fără calculul lambda , proiectul Jigsaw și o parte din îmbunătățirile proiectului Coin [ 19] ) și Java Standard Edition 8 (toate restul), programate pentru sfârșitul anului 2012.
În noua versiune, numită Java Standard Edition 7 (Java Platform, Standard Edition 7), pe lângă remedierea unui număr mare de erori, au fost introduse mai multe inovații. Deci, de exemplu, nu pachetul proprietar JDK , ci implementarea sa deschisă OpenJDK a fost folosită ca implementare de referință a Java Standard Edition 7 , iar lansarea noii versiuni a platformei a fost pregătită în strânsă cooperare între inginerii Oracle și membrii grupului. ecosistemul Java global, comitetul JCP (Java Community Process) și de către comunitatea OpenJDK . Toate binarele de implementare de referință Java Standard Edition 7 furnizate de Oracle sunt construite pe baza de cod OpenJDK , iar implementarea de referință în sine este complet open-source sub licența GPLv2 cu excepții GNU ClassPath pentru a permite conectarea dinamică la produsele proprietare. Alte inovații includ integrarea unui set de îmbunătățiri mici ale limbajului Java dezvoltate de proiectul Coin, suport adăugat pentru limbaje de programare cu tastare dinamică, cum ar fi Ruby , Python și JavaScript , suport pentru încărcarea claselor după URL , o stivă XML actualizată care include JAXP 1.4, JAXB 2.2a și JAX-WS 2.2 și altele [20] .
În cele 5 zile înainte de lansarea Java Standard Edition 7, au fost descoperite câteva erori grave în optimizarea buclei calde, care este activată implicit și provoacă blocarea mașinii virtuale Java. Specialiștii Oracle nu au putut remedia erorile găsite într-un timp atât de scurt, dar au promis că vor fi remediate în a doua actualizare (Java 7 Update 2) și parțial în prima [21] .
Lista inovațiilorVersiunea a fost lansată pe 19 martie 2014. Nume de cod Octopus.
Lista inovațiilorDin cauza dificultăților de implementare a sistemului modular în cadrul proiectului Jigsaw, lansarea versiunii, programată inițial pentru 22 septembrie 2016, a fost amânată de mai multe ori: mai întâi, data a fost mutată pe 23 martie 2017 , apoi pe 27 iulie 2017. , iar apoi la 21 iulie 2017. Septembrie 2017 [25] [26] [27] .
Ultima dată a devenit data oficială de lansare a versiunii [28] .
Lista inovațiilorData lansării: 20 martie 2018 [38] .
Lista inovațiilorLista oficială parțială a funcțiilor și planul de lansare se află pe site-ul web OpenJDK .
Lista oficială parțială a funcțiilor și planul de lansare se află pe site-ul web OpenJDK . Data lansării este 25 septembrie 2018.
Lista inovațiilorÎn Java, există mai multe familii majore de tehnologii:
Microsoft și- a dezvoltat propria implementare JVM numită Microsoft Java Virtual Machine.(MSJVM) [58] , care a fost inclus în diverse sisteme de operare începând cu Windows 98 (inclus și în Internet Explorer de la versiunea 3 și mai mare, ceea ce a făcut posibilă utilizarea MSJVM în Windows 95 și Windows NT 4 după instalarea IE3 + pe acestea). OS).
MSJVM a avut diferențe semnificative față de Sun Java, rupând în multe feluri conceptul fundamental de portabilitate a programelor între diferite platforme:
Integrarea strânsă a Java cu DCOM și Win32 a pus sub semnul întrebării paradigma multiplatformă a limbajului. Ulterior, acesta a fost motivul proceselor de la Sun Microsystems împotriva Microsoft. Curtea a fost de partea Sun Microsystems. În cele din urmă, s-a ajuns la un acord între cele două companii cu privire la posibilitatea prelungirii perioadei de suport oficial pentru utilizatorii JVM non-standard Microsoft până la sfârșitul anului 2007 [58] .
În 2005, Microsoft a introdus un limbaj asemănător Java J# pentru platforma .NET , care nu corespunde specificației oficiale a limbajului Java și a fost ulterior exclus din setul de instrumente standard pentru dezvoltatori Microsoft Visual Studio , începând cu Visual Studio 2008 [59] .
Limbajul Java este utilizat în mod activ pentru a crea aplicații mobile pentru sistemul de operare Android. În același timp, programele sunt compilate în bytecode non-standard pentru a fi utilizate de mașina lor virtuală Dalvik (începând cu Android 5.0 Lollipop , mașina virtuală a fost înlocuită de ART ). Pentru o astfel de compilare se folosește un instrument suplimentar, și anume Android SDK ( Software Development Kit ), dezvoltat de Google .
Dezvoltarea aplicației se poate face în Android Studio , NetBeans , Eclipse folosind pluginul Android Development Tools (ADT) sau IntelliJ IDEA . Versiunea JDK trebuie să fie 5.0 sau mai mare.
Pe 8 decembrie 2014, Android Studio a fost recunoscut de Google ca mediu de dezvoltare oficial pentru sistemul de operare Android.
Următoarele proiecte de succes au fost implementate folosind tehnologii Java ( J2EE ): RuneScape , Amazon [60] [61] , eBay [62] [63] , LinkedIn [64] , Yahoo! [65] .
Următoarele companii se concentrează în principal pe tehnologiile Java ( J2EE- ): SAP , IBM , Oracle . În special, Oracle Database DBMS include ca componentă un JVM, care oferă posibilitatea de a programa direct DBMS-ul în limbajul Java, incluzând, de exemplu, procedurile stocate [66] .
Programele scrise în Java au reputația de a fi mai lente și de a ocupa mai multă RAM decât cele scrise în C [6] . Cu toate acestea, viteza de execuție a programelor scrise în limbajul Java a fost îmbunătățită semnificativ odată cu lansarea în 1997-1998 a așa-numitului compilator JIT în versiunea 1.1, pe lângă alte caracteristici ale limbajului pentru a sprijini o analiză mai bună a codului (cum ar fi clasele interne, clasa StringBuffer[doc 5] , calcule logice simplificate și așa mai departe). În plus, mașina virtuală Java a fost optimizată - din 2000, mașina virtuală HotSpot a fost folosită pentru aceasta . Din februarie 2012, codul Java 7 este de aproximativ 1,8 ori mai lent decât codul C [67] .
Unele platforme oferă suport de execuție hardware pentru Java [68] . De exemplu, microcontrolere care rulează cod Java în hardware în loc de un JVM software și procesoare bazate pe ARM care acceptă execuția bytecode Java prin opțiunea Jazelle.
Există doar 8 tipuri primitive (scalare, simple) în Java : boolean, byte, char, short, int, long, float, double. Există, de asemenea, un al nouălea tip primitiv auxiliar - void, cu toate acestea, variabilele și câmpurile de acest tip nu pot fi declarate în cod, iar tipul în sine este folosit doar pentru a descrie clasa care îi corespunde, pentru utilizare în reflecție : de exemplu, folosind Void[doc. 6] puteți afla dacă o anumită metodă este de tip void: Hello.class.getMethod("main", String[].class).getReturnType() == Void.TYPE.
Lungimile și intervalele de valori ale tipurilor primitive sunt definite de standard, nu de implementare și sunt enumerate în tabel. Tipul char a fost făcut pe doi octeți pentru comoditatea localizării (unul dintre principiile ideologice ale Java): când a fost format standardul, Unicode -16 exista deja, dar nu Unicode-32. Deoarece nu a mai rămas niciun tip de un singur octet, a fost adăugat un nou tip de octet, iar în Java, spre deosebire de alte limbi, nu este nesemnat. Tipurile floatși doublepot avea valori speciale și „nu un număr” ( NaN ). Pentru tipul dublu, acestea sunt notate cu , , ; pentru tip - același, dar cu un prefix în loc de . Valorile minime și maxime acceptate de și tipuri sunt , de asemenea, standardizate. Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITYDouble.NaNfloatFloatDoublefloatdouble
Tip de | Lungime (în octeți) | Interval sau set de valori |
---|---|---|
boolean | 1 în matrice, 4 în variabile [69] | adevarat fals |
octet | unu | −128..127 |
char | 2 | 0..2 16 −1 sau 0..65535 |
mic de statura | 2 | −2 15 ..2 15 −1 sau −32768..32767 |
int | patru | −2 31 ..2 31 −1 sau −2147483648..2147483647 |
lung | opt | −2 63 ..2 63 −1 sau aproximativ −9.2 10 18 ..9.2 10 18 |
pluti | patru | -(2-2 −23 ) 2 127 ..(2-2 −23 ) 2 127 , sau aproximativ −3.4 10 38 ..3.4 10 38 , și de asemenea , , NaN |
dubla | opt | -(2-2 −52 ) 2 1023 ..(2-2 −52 ) 2 1023 , sau aproximativ −1.8 10 308 ..1.8 10 308 , precum și , , NaN |
O astfel de standardizare rigidă a fost necesară pentru a face limbajul independent de platformă, ceea ce este una dintre cerințele ideologice pentru Java. Cu toate acestea, rămâne o mică problemă cu independența platformei. Unele procesoare folosesc registre de 10 octeți pentru stocarea intermediară a rezultatelor sau îmbunătățesc acuratețea calculelor în alte moduri. Pentru a face Java cât mai interoperabil între diferite sisteme, orice modalitate de a îmbunătăți acuratețea calculelor a fost interzisă în versiunile timpurii. Cu toate acestea, acest lucru a dus la o performanță mai lentă. S-a dovedit că puțini oameni au nevoie de deteriorarea acurateței de dragul independenței platformei, mai ales dacă trebuie să plătească pentru aceasta încetinind activitatea programelor. După numeroase proteste, această interdicție a fost anulată, dar a fost adăugat cuvântul cheie strictfp, care interzice creșterea preciziei.
Transformări în operații matematiceLimbajul Java are următoarele reguli:
Această metodă de conversie implicită a tipurilor încorporate coincide complet cu conversia tipului în C / C++ [70] .
Limbajul Java are doar obiecte create dinamic. Variabilele tip obiect și obiectele din Java sunt entități complet diferite. Variabilele unui tip de obiect sunt referințe , adică analogi ale pointerilor către obiecte create dinamic. Acest lucru este subliniat de sintaxa declarației de variabile. Deci codul C++ ar putea arăta astfel:
dublu a [ 10 ][ 20 ] ; foo b ( 30 );Dar același lucru în Java va arăta foarte diferit:
dublu [][] a = dublu nou [ 10 ][ 20 ] ; Foo b = nou Foo ( 30 );În timpul atribuirilor, trecerii la subrutine și comparărilor, variabilele obiect se comportă ca pointeri, adică adresele obiectelor sunt atribuite, copiate și comparate. Și atunci când accesați câmpuri de date sau metode ale unui obiect cu o variabilă obiect, nu sunt necesare operații speciale de dereferire - accesul se efectuează ca și cum variabila obiect ar fi obiectul însuși.
Variabilele obiect sunt variabile de orice tip, cu excepția celor primitive. Nu există indicatoare explicite în Java. Spre deosebire de pointerii din C, C++ și alte limbaje de programare, referințele în Java sunt foarte sigure datorită restricțiilor stricte privind utilizarea lor.
Datorită unor astfel de restricții special introduse, manipularea directă a memoriei la nivelul adreselor fizice este imposibilă în Java (deși valoarea referinței care indică la nimic este definită: null).
Dacă este nevoie de un pointer către un tip primitiv, se folosesc clase de wrapper de tipuri primitive: Boolean, Byte, Character, Short, Integer, Long, Float, Double.
Duplicarea link-urilor și clonareaLa alocare, obiectul nu este copiat, deoarece variabilele obiect sunt variabile de referință. Deci, dacă scrii
Foo foo , bar ; ... bar = foo ;atunci adresa va fi copiată din variabilă fooîn variabilă bar. Adică fooși barva indica aceeași zonă de memorie, adică același obiect; încercarea de a schimba câmpurile obiectului referit de variabilă foova schimba obiectul referit de variabilă barși invers. Dacă este necesar să se obțină încă o copie a obiectului original, ei folosesc fie o metodă (funcție membru, în terminologia C++) clone ()care creează o copie a obiectului, fie (mai rar) un constructor de copiere ( constructori în Java ). nu poate fi virtuală, deci o instanță a unei clase descendente va fi copiată incorect de către constructorul clasei strămoși; metoda clonării invocă constructorul dorit și astfel eludează această limitare).
Metoda clone()[doc. 7] necesită o clasă pentru a implementa o interfață Cloneable[doc. 8] . Dacă o clasă implementează interfața Cloneable, aceasta va copia implicit clone()toate câmpurile ( copie superficială ). Dacă doriți să clonați câmpuri (precum și câmpurile lor și așa mai departe) în loc să copiați, trebuie să înlocuiți clone(). Definirea și utilizarea unei metode clone()este adesea o sarcină netrivială [72] .
Inițializarea variabileiToate variabilele fie necesită o definiție explicită, fie sunt completate automat cu zerouri (0, null, false). Astfel, heisenbug -urile asociate cu utilizarea accidentală a memoriei neinițializate, caracteristice limbajelor de nivel scăzut precum C , dispar .
Colectarea gunoiuluiÎn limbajul Java, nu este posibil să ștergeți în mod explicit un obiect din memorie - în schimb, colectarea gunoiului este implementată . Un truc tradițional pentru a oferi colectorului de gunoi un „indiciu” pentru a dealoca memoria este să setați o variabilă la null null, care poate fi eficientă atunci când trebuie să dealocați un obiect care nu mai este necesar și este referit într-un obiect cu viață lungă [73 ] . Acest lucru, însă, nu înseamnă că obiectul înlocuit cu valoare nullva fi șters cu siguranță și imediat, dar există garanția că acest obiect va fi șters în viitor. Această tehnică îndepărtează doar referința la obiect, adică dezlega indicatorul de obiectul din memorie. În acest caz, trebuie avut în vedere că obiectul nu va fi șters de către colectorul de gunoi atâta timp cât cel puțin o referință din variabilele sau obiectele utilizate indică către acesta. Există, de asemenea, metode pentru inițierea unei colectări forțate a gunoiului, dar nu se garantează că vor fi apelate de runtime și nu sunt recomandate pentru utilizare normală.
Java nu este un limbaj procedural: orice funcție poate exista doar în cadrul unei clase. Acest lucru este subliniat de terminologia limbajului Java, unde nu există concepte de „funcție” sau „funcție membru” ( funcția membru în limba engleză ), ci doar o metodă . Funcțiile standard au devenit și ele metode. De exemplu, în Java nu există nicio funcție , dar există o metodă de clasă (care conține, pe lângă , metode , , , și multe altele). Constructorii din Java nu sunt considerați metode. Nu există destructori în Java și o metodă nu ar trebui în niciun caz să fie considerată analogă cu un destructor. sin()Math.sin()Mathsin()cos()exp()sqrt()abs()finalize()
ConstructoriUn constructor este o metodă specială care este apelată în mod necesar atunci când este creat un nou obiect, adică un obiect (o instanță a unei clase) nu poate fi creat fără apelarea constructorului de clasă. Nu este întotdeauna convenabil să inițializați toate variabilele unei clase atunci când aceasta este instanțiată, astfel încât variabilele de instanță sunt adesea declarate în corpul unui constructor, dar sunt inițializate ca argumente de constructor atunci când clasa este instanțiată. Uneori este mai ușor să aveți unele valori create implicit atunci când obiectul este creat. În acest caz, variabilele sunt declarate și inițializate în corpul constructorului.
Un constructor inițializează un obiect direct în momentul creării. Numele constructorului este același cu numele clasei, inclusiv majuscule, iar sintaxa unui constructor este similară cu cea a unei metode fără valoare returnată.
private int Cat (); // așa arată metoda numită Cat Cat (); // așa arată constructorul clasei CatSpre deosebire de o metodă, un constructor nu returnează niciodată nimic.
Un constructor definește acțiunile care trebuie întreprinse atunci când un obiect al unei clase este creat și este o parte importantă a unei clase. De regulă, programatorii încearcă să specifice în mod explicit un constructor. Dacă nu există un constructor explicit, atunci Java va crea automat unul (gol) pentru utilizare implicită.
Ca exemplu, luați în considerare o clasă Boxcare reprezintă o descriere a unei casete. Constructorul clasei va seta pur și simplu dimensiunile inițiale pentru casetă.
classBox { int width ; _ // box width int height ; // box height int depth ; // adâncimea casetei // Caseta constructoare ( int a , int b ) { width = a ; inaltime = b ; adâncime = 10 ; } // calculează volumul casetei int getVolume () { return width * height * depth ; } } Metode și câmpuri staticeJava (precum și C++) utilizează câmpuri statice și metode statice ( metoda statică - în teoria programării sunt numite și metode de clasă), care sunt specificate folosind cuvântul cheie . Câmpurile statice (variabilele de clasă) au aceeași semnificație ca în C++: fiecare astfel de câmp este proprietatea clasei, deci nu este nevoie să creați instanțe ale clasei corespunzătoare pentru a accesa câmpurile statice. static
De exemplu, funcțiile matematice implementate în clasa Math[doc. 9] sunt doar metode statice din această clasă. Prin urmare, ele pot fi apelate direct din clasă fără a crea o instanță a acesteia, de exemplu:
dublu x = Math . păcat ( 1 );Crearea unei instanțe a unei clase statice este interzisă folosind un constructor privat. De exemplu, crearea unei instanțe a unei clase Mathva avea ca rezultat o eroare de compilare:
Math m = new Math (); // Eroare: Math() are acces privat în java.lang.Math double x = m . păcat ( 1 ); // Obiectul nu ar avea o metodă sin, deoarece este staticDeoarece metodele statice există independent de obiecte (instanțe ale unei clase), ele nu au acces la câmpurile și metodele obișnuite (non-statice) ale clasei date. În special, atunci când implementați o metodă statică, NU TREBUIE să utilizați identificatorul this.
Caracteristica de import static vă permite să apelați funcții și constante statice fără a specifica o clasă. Exemplu fără import static:
dublu x = Math . sin ( Math . tan ( Math . sqrt ( y )) + Math . floor ( 24,5 )) + Math . cos ( 42 * Math . PI );Același exemplu, dar cu importuri statice:
import static java.lang.Math.* ; ... dublu x = sin ( tan ( sqrt ( y )) + floor ( 24,5 )) + cos ( 42 * PI ); Finalizare (finală)Cuvântul cheie final(final) are semnificații diferite atunci când descrie un câmp, o metodă sau o clasă.
În Java, metodele care nu sunt declarate explicit ca static, finalsau private, sunt virtuale în terminologia C++: apelarea unei metode definite diferit în clasele de bază și moștenirea claselor efectuează întotdeauna o verificare la timp de execuție.
O metodă abstractă (modificator abstract) în Java este o metodă care are parametri și un tip de returnare, dar fără corp. O metodă abstractă este definită în clase derivate. Analogul unei metode abstracte în C++ este o funcție virtuală pură. Pentru ca o clasă să poată descrie metode abstracte, clasa în sine trebuie de asemenea să fie declarată abstractă. Obiectele de clasă abstracte nu pot fi create.
InterfețeCel mai înalt grad de abstractizare în Java este interfața (modificatorul interface). Interfața conține în mare parte metode abstracte care au un nivel de acces public: descriptori abstractși publicnici măcar nu sunt necesari pentru aceștia. Cu toate acestea, începând cu Java 8 și 9, a fost introdusă capacitatea de utilizare în interfețe.
- Java 8: metode statice ( static) și metode implicite ( default);
- Java 9: metode cu nivel de acces private.
Aceste metode conțin un corp, ceea ce înseamnă că nu sunt abstracte, dar într-o implementare specifică a interfeței, default-metodele pot fi suprascrise.
O interfață în Java nu este considerată o clasă, deși este, de fapt, o clasă complet abstractă. O clasă poate moșteni/ extinde ( extends) o altă clasă sau poate implementa ( implements) o interfață. De asemenea, o interfață poate moșteni/extinde ( extends) o altă interfață.
În Java, o clasă nu poate moșteni de la mai mult de o clasă, dar poate implementa mai multe interfețe. Moștenirea multiplă a interfețelor nu este interzisă, adică o interfață poate fi moștenită de la mai multe.
Interfețele pot fi folosite ca tipuri de parametri de metodă. Interfețele nu pot fi instanțiate.
Interfețe de marcareJava are interfețe care nu conțin metode de implementare, dar sunt tratate într-un mod special de către JVM: Cloneable, Serializable, RandomAccess, Remote.
Șabloane în Java (generice)Începând cu Java 5.0, în limbaj a apărut un mecanism de programare generic - șabloane care sunt în exterior apropiate de șabloanele C++. Folosind o sintaxă specială în descrierea claselor și metodelor, puteți specifica parametrii de tip care pot fi utilizați în descriere ca tipuri de câmpuri, parametri și valori returnate ale metodelor.
// Clasa de declarare a clasei generice GenericClass < E > { E getFirst () { ... } void add ( E obj ) { ... } } // Folosind o clasă generică în codul GenericClass < String > obj = new GenericClass <> (); obj . adăugați ( "qwerty" ); Șirul p = obj . getFirst ();Este permisă declararea generică a claselor, interfețelor și metodelor. În plus, sintaxa acceptă declarații de parametri de tip restricționat: specificarea unui construct de tip în declarație <T extends A & B & C...>necesită ca parametrul de tip T să implementeze interfețele A, B, C și așa mai departe.
Spre deosebire de șabloanele C#, șabloanele Java nu sunt acceptate de runtime - compilatorul creează pur și simplu bytecode, în care nu mai există șabloane. Implementarea șabloanelor în Java este fundamental diferită de implementarea mecanismelor similare în C++: compilatorul nu generează o variantă separată a unei clase sau metode șablon pentru fiecare caz de utilizare a unui șablon, ci pur și simplu creează o singură implementare bytecode care conține verificările de tip și conversiile necesare. Acest lucru duce la o serie de restricții privind utilizarea șabloanelor în programele Java.
Se verifică calitatea de membru al claseiÎn Java, puteți verifica în mod explicit cărei clase îi aparține un obiect. Expresia foo instanceof Fooeste egală truedacă obiectul fooaparține unei clase Foosau descendentului acesteia sau implementează o interfață Foo(sau, mai general, moștenește o clasă care implementează o interfață care moștenește Foo).
În continuare, funcția getClass()[doc. 10] , definit pentru toate obiectele, produce un obiect de tip Class<?>. Pentru fiecare clasă, este creat cel mult un obiect de tip care o descrie Class, astfel încât aceste obiecte pot fi comparate. Deci, de exemplu, foo.getClass() == bar.getClass()va fi adevărat dacă obiectele fooși baraparțin aceleiași clase.
În plus, un obiect de Class<?>orice tip poate fi obținut astfel: Integer.class, Object.class.
Compararea directă a claselor nu este întotdeauna cel mai bun mijloc de a verifica calitatea de membru al clasei. Adesea, o funcție este folosită în schimb isAssignableFrom(). Această funcție este definită pe un obiect tip Classși ia ca Class<?>parametru un obiect tip. Astfel, apelul Foo.class.isAssignableFrom(Bar.class)va reveni truedacă Fooeste un strămoș al clasei Bar. Deoarece toate obiectele sunt descendenți de tip Object, apelul Object.class.isAssignableFrom()va reveni întotdeauna true.
În legătură cu funcțiile menționate ale obiectului tip Class, funcțiile isInstance[doc. 11] (echivalent cu instanceof), precum și cast()(convertă parametrul într-un obiect din clasa selectată).
Gestionarea erorilor în Java este similară cu gestionarea erorilor în C++ , cu excepția necesității unui finally. Această diferență se datorează faptului că Java nu poate adera la conceptul RAII din cauza prezenței unui colector de gunoi, iar eliberarea automată a resurselor în destructor poate avea loc într-o ordine imprevizibilă la intervale arbitrare.
Tratarea erorilor se realizează folosind operatorii try, catchși finally. Eroarea aruncată este descrisă de un obiect dintr-o anumită clasă care moștenește de la Throwable[doc. 12] și corespunzătoare tipului de eroare. În interiorul blocului tryeste cod care poate arunca o excepție, iar blocul catchprinde tipurile de erori specificate de programator. În acest caz, puteți specifica mai multe blocuri catchpentru a gestiona diferite clase de erori sau multi-catch pentru a gestiona mai multe erori. Blocul este opțional, dar dacă este prezent, este executat indiferent de apariția unei erori și are scopul de a elibera resursele finallyalocate în timpul funcționării blocului .try
Din Java 7, interfața AutoCloseable[doc. 13] , care vă permite să implementați clase care eliberează automat resurse. Obiectele unor astfel de clase trebuie create între paranteze înainte de try. Un exemplu simplu de dealocare automată a resurselor este citirea conținutului unui fișier:
import java.io.* ; clasă publică principală { public static void main ( String [] args ) aruncă IOException { if ( args . lungime < 2 ) { Sistem . greseala . println ( "Niciun nume de fișier specificat." ); întoarcere ; } String nume de fișier = args [ 1 ] ; // Fișierul deschis va fi închis automat din greșeală încercați ( BufferedReader reader = nou BufferedReader ( nou FileReader ( nume fișier ))) { linie șir ; pentru ( int n = 1 ; ( line = cititor . readLine ()) != null ; ++ n ) { Sistem . afară . println ( n + ": " + linie ); } } catch ( FileNotFoundException e ) { Sistem . greseala . println ( "Fișierul specificat nu a fost găsit." ); } // in cele din urma { // reader.close(); // închidere automată a resurselor // } } }Java aderă la conceptul de specificare obligatorie a claselor de eroare pe care o metodă le poate arunca. Acest lucru se face folosind un cuvânt cheie throwsdupă descrierea metodei. Dacă metoda nu specifică o clasă de excepție (sau strămoșul său) care poate fi aruncată din metodă, atunci aceasta va provoca o eroare de compilare. Conceptul trebuia să facă codul să se auto-documenteze, indicând ce excepții poate arunca o anumită metodă, dar în practică rareori se justifică, deoarece, din cauza diverselor circumstanțe, un programator poate specifica o clasă ca excepție de aruncat Exceptionsau poate include problematică . părți ale unei metode într-un bloc try... catchpentru a ignora erorile individuale sau - în bloc try... finally, ascund toate erorile posibile. Dezavantajul conceptului este, de asemenea, că programatorul însuși trebuie să definească și să prescrie excepțiile pe care metoda le poate arunca [74] .
Ideea spațiilor de nume este încorporată în pachetele Java .
Numele pachetului Java este latin (minuscule și majuscule) cu numere (nu primul din rând) și un caracter de subliniere (nu primul și nu ultimul), care nu sunt instrucțiuni de limbă (notă if, null), separate prin puncte .
Exemple de nume corecte:
Exemple de nume greșite:
Pachetele conțin clase, interfețe, enumerări, adnotări (etc.) ale căror nume sunt latine (minuscule și majuscule) cu numere (nu primul dintr-o linie). Într-un fișier poate exista o singură clasă publică, interfață (etc.). Numele clasei publice, al interfeței (etc.) din fișier trebuie să se potrivească cu numele fișierului. Fiecare clasă are propriul său spațiu de nume pentru funcții, variabile și subclase, subinterfețe (etc.), și puteți obține o subclasă a unei clase folosind OuterClass.InnerClasssau puteți utiliza OuterClass$InnerClass, deci nu este recomandată utilizarea simbolului dolar în numele clasei.
Cod program „Bună, lume!” .
clasa buna lume { public static void main ( String [] args ) { Sistem . afară . println ( "Bună ziua, lume!" ); } } Un exemplu de utilizare a genericelor import java.util.List ; import java.util.ArrayList ; public class Sample { public static void main ( String [] args ) { // Creați un obiect dintr-un șablon. Listă < String > șiruri = new ArrayList <> (); corzi . adauga ( "Bună ziua" ); corzi . adaugă ( „lume” ); corzi . adauga ( "!" ); for ( var string : strings ) { System . afară . print ( șir + " " ); } } } Un exemplu de utilizare a reflexiei import java.lang.reflect.Field ; import java.lang.reflect.Method ; class TestClass { private int value ; public int getValue () { return value ; } public void setValue ( int valueIn ) { this . valoare = valoareIn ; } } public class Main { public static void main ( String [] args ) { var testClass = new TestClass (); pentru ( câmp var : testClass . getClass (). getDeclaredFields ()) { System . afară . printf ( "nume:%s, tip:%s \n" , câmp .getName (), câmp .getType (). getCanonicalName ( ) ); } pentru ( metoda var : testClass . getClass (). getDeclaredMethods ()) { System . afară . printf ( „nume:%s, tip returnat:%s \n” , metoda .getName (), metoda .getReturnType (). getCanonicalName ( ) ); } } }Adnotări :
Exemplu de adnotare import java.lang.annotation.ElementType ; import java.lang.annotation.Retention ; import java.lang.annotation.RetentionPolicy ; import java.lang.annotation.Target ; @Retention ( RetentionPolicy . RUNTIME ) @Target ( ElementType . TYPE ) public @interface MyAnnotation { public boolean value () implicit false ; } @MyAnnotation ( valoare = adevărat ) clasă publică TestClass { } public class Main { public static void main ( String [] args ) { var testClass = new TestClass (); var myAnnotation = testClass . getClass (). getAnnotation ( MyAnnotation . class ); if ( myAnnotation != null ) { System . afară . printf ( "valoare:%s \n" , myAnnotation . valoare ()); } } } ![]() | ||||
---|---|---|---|---|
Site-uri tematice | ||||
Dicționare și enciclopedii | ||||
|
Java | |
---|---|
Platforme | |
Sun Technologies | |
Tehnologii cheie ale terților | |
Poveste |
|
Proprietățile limbajului | |
Limbaje de scripting |
|
conferințe Java |
|
Limbaje de programare | |
---|---|
|