Java | |
---|---|
Sprog klasse | multi-paradigme programmeringssprog , JVM sprog og software |
Dukkede op i | 1995 |
Forfatter | James Gosling og Sun Microsystems |
Udvikler | Sun Microsystems og Oracle |
Filtypenavn _ | .java, .class, .jar, .jadeller.jmod |
Frigøre | Java SE 18.0.2.1 ( 18. august 2022 ) |
Blev påvirket | C++ , C , Ada , Simula 67 , Smalltalk , Objective-C , Object Pascal , Oberon , Eiffel , Modula-3 , Mesa , Simula , C# , UCSD Pascal , wrapper , Variabel funktion , Java-annotering , Nicklaus Wirth , Patrick Naughton [d] og foreach |
Licens | GNU GPL [1] |
Internet side | oracle.com/ru/java/ |
Mediefiler på Wikimedia Commons |
Java [ca. 1] er et stærkt indskrevet objektorienteret programmeringssprog til generelle formål udviklet af Sun Microsystems (senere erhvervet af Oracle ). Udvikling er drevet af et fællesskab organiseret gennem Java Community Process ; sproget og de underliggende teknologier, der implementerer det, distribueres under GPL-licensen . Varemærkerettigheder ejes af Oracle Corporation .
Java-applikationer oversættes normalt til speciel bytekode , så de kan køre på enhver computerarkitektur , hvor der er en implementering af Java Virtual Machine . Den officielle udgivelsesdato er den 23. maj 1995. Det rangerer højt i programmeringssprogs popularitetsrangeringer (2. plads i IEEE Spectrum (2020) [2] og TIOBE (2021) [3] rangeringer ).
Sproget blev oprindeligt kaldt Oak ("Oak"), udviklet af James Gosling til programmering af elektroniske forbrugere. Fordi et sprog med det navn allerede eksisterede, blev Oak omdøbt til Java [4] . Opkaldt efter kaffemærket Java, som til gengæld fik navnet på øen af samme navn ( Java ), så sprogets officielle emblem viser en kop varm kaffe. Der er en anden version af oprindelsen af sprogets navn, forbundet med en hentydning til en kaffemaskine som et eksempel på en husholdningsenhed til programmering, som sproget oprindeligt blev oprettet. I overensstemmelse med etymologi blev sprogets navn i russisksproget litteratur fra slutningen af det tyvende århundrede til de første år af det enogtyvende århundrede ofte oversat til Java og ikke transskriberet.
Som et resultat af projektet så verden en fundamentalt ny enhed, Star7 pocket personal computer [5] , som var forud for sin tid med mere end 10 år, men på grund af de høje omkostninger på $ 50, kunne den ikke revolutionere teknologiens verden og blev glemt.
Star7-enheden var ikke populær i modsætning til programmeringssproget Java og dets miljø. Den næste fase i sprogets liv var udviklingen af interaktivt tv. I 1994 blev det klart, at interaktivt tv var en fejltagelse.
Siden midten af 1990'erne er sproget blevet meget brugt til at skrive klientapplikationer og serversoftware . Samtidig vandt teknologien med Java-applets , grafiske Java-applikationer indlejret i websider, en vis popularitet; Med fremkomsten af dynamiske websidefunktioner i 2000'erne blev teknologien mindre udbredt.
Webudvikling bruger Spring Framework ; Javadoc -værktøjet bruges til dokumentation .
Java -programmer er oversat til Java bytecode , som udføres af Java Virtual Machine (JVM), et program, der behandler byte-kode og sender instruktioner til hardwaren som en fortolker .
Fordelen ved denne måde at udføre programmer på er den fuldstændige uafhængighed af bytekoden fra operativsystemet og hardwaren , som giver dig mulighed for at køre Java-applikationer på enhver enhed, som der er en tilsvarende virtuel maskine til. Et andet vigtigt træk ved Java-teknologi er et fleksibelt sikkerhedssystem, hvor afviklingen af programmet er fuldstændig styret af den virtuelle maskine. Enhver handling, der overskrider programmets indstillede tilladelser (såsom forsøg på uautoriseret adgang til data eller oprettelse af forbindelse til en anden computer), forårsager en øjeblikkelig afbrydelse.
Ofte omfatter ulemperne ved konceptet med den virtuelle maskine ydeevneforringelse. En række forbedringer øgede en smule hastigheden på Java-programmer:
Ifølge webstedet shootout.alioth.debian.org, for syv forskellige opgaver, er udførelsestiden i Java i gennemsnit halvanden til to gange længere end for C/C++, i nogle tilfælde er Java hurtigere, og i nogle tilfælde er det 7 gange langsommere [ 6] . På den anden side, for de fleste af dem, var hukommelsesforbruget for en Java-maskine 10 til 30 gange større end for et C/C++-program. Bemærkelsesværdig er også en undersøgelse foretaget af Google , ifølge hvilken der er en væsentlig lavere ydeevne og højere hukommelsesforbrug i testcases i Java sammenlignet med lignende programmer i C ++ [7] [8] [9] .
Idéerne bag konceptet og forskellige implementeringer af Java virtual machine-miljøet har inspireret mange entusiaster til at udvide listen over sprog, der kunne bruges til at skabe programmer, der kører på en virtuel maskine [10] . Disse ideer er også udtrykt i Common Language Infrastructure ( CLI )-specifikationen , der understøttede .NET -platformen fra Microsoft .
Java-udvikling begyndte i 1990, den første officielle version - Java 1.0 - blev først udgivet den 21. januar 1996.
Den anden version blev udgivet den 19. februar 1997 [11] .
Udgivelsesdato 8. december 1998 [12] . Kodenavn Legeplads. I dette tilfælde er der forvirring. Bøger er blevet udgivet, for eksempel Beginning Java 2 af Ivor Horton (mar 1999), faktisk på J2SE 1.2 (tidligere kaldet Java 2). Imidlertid udgives den dag i dag sådanne bøger, for eksempel: H. M. Deitel, P. J. Deitel, S. I. Santry. Java-programmeringsteknologier 2. Distribuerede applikationer (2011).
På et tidspunkt, hvor Java 2 er kendt for at være blevet historisk afløst af efterfølgende udgivelser, er sådanne bogtitler vildledende med hensyn til, hvilken version af Java de egentlig er skrevet om. Hvis J2SE 1.2 anses for at være Java 2, men forfatterne af Java 2-bøger accepterer JDK 7, fører dette til fuldstændig forvirring.
Udgivelsesdato 8. maj 2000. Kodenavn Kestrel.
Udgivelsesdato 6. februar 2002. Kodenavn Merlin.
Java 5.0-specifikationen blev udgivet den 30. september 2004 med kodenavnet Tiger. Siden denne version er den officielle indeksering blevet ændret, i stedet for Java 1.5 er det mere korrekt at kalde Java 5.0. Suns interne indeksering forbliver den samme - 1,x. Mindre ændringer er nu inkluderet uden at ændre indeksering, hertil bruges ordet "Opdatering" eller bogstavet "u", for eksempel Java Development Kit 5.0 Update 22. Det antages, at opdateringer kan indeholde både fejlrettelser og små tilføjelser til API, JVM.
I denne version har udviklerne lavet en række grundlæggende tilføjelser til sproget:
Versionen blev udgivet den 11. december 2006 med kodenavnet Mustang. Den officielle indeksering er blevet ændret - i stedet for den forventede 6.0 er versionen angivet som 6. Mindre ændringer, som i Java 5.0, er lavet til almindelige versionsopdateringer, for eksempel Java Standard Edition Development Kit 6 Update 27. Følgende ændringer er blevet lavet:
Udgivelsesdato 8. oktober 2013.
JavaFX 2.2 er inkluderet i Java SE 7 opdatering 6 [15] . Fra version 11 sendes modulet separat fra JDK [16] .
Udgivelsesdato 10. oktober 2013. Kodenavn Micro Edition.
Versionen blev udgivet den 28. juli 2011, kodenavnet Dolphin [17] . Den endelige version af Java Standard Edition 7 indeholdt ikke alle de tidligere planlagte ændringer. I henhold til udviklingsplanen (plan "B") [18] vil inddragelsen af innovationer blive opdelt i to dele: Java Standard Edition 7 (uden lambda-regningen , Jigsaw-projektet og en del af forbedringerne af Coin-projektet [ 19] ) og Java Standard Edition 8 (alle resten), planlagt til slutningen af 2012.
I den nye version, kaldet Java Standard Edition 7 (Java Platform, Standard Edition 7), blev der ud over at rette en lang række fejl introduceret flere innovationer. Så for eksempel blev ikke den proprietære JDK -pakke , men dens åbne implementering OpenJDK brugt som referenceimplementering af Java Standard Edition 7 , og udgivelsen af den nye version af platformen blev udarbejdet i tæt samarbejde mellem Oracle -ingeniører og medlemmer af globale Java-økosystem, JCP -udvalget (Java Community Process) og af OpenJDK . Alle Oracle-leverede Java Standard Edition 7-referenceimplementeringsbinære filer er bygget oven på OpenJDK -kodebasen , og selve referenceimplementeringen er fuldt open source under GPLv2 -licensen med GNU ClassPath-undtagelser for at tillade dynamisk linkning til proprietære produkter. Andre innovationer inkluderer integration af et sæt små Java-sprogforbedringer udviklet af Coin-projektet, tilføjet understøttelse af dynamisk indtastede programmeringssprog såsom Ruby , Python og JavaScript , understøttelse af indlæsning af klasser efter URL , en opdateret XML - stak, der inkluderer JAXP 1.4, JAXB 2.2a og JAX-WS 2.2 og andre [20] .
I de 5 dage før udgivelsen af Java Standard Edition 7 blev der opdaget flere alvorlige fejl i hot loop-optimering, som er aktiveret som standard og får Java Virtual Machine til at gå ned. Oracle-specialister kunne ikke rette de fundne fejl på så kort tid, men lovede at de ville blive rettet i den anden opdatering (Java 7 Update 2) og delvist i den første [21] .
Liste over innovationerVersionen blev udgivet den 19. marts 2014. Kodenavn Octopus.
Liste over innovationerPå grund af vanskeligheder med at implementere det modulære system i Jigsaw-projektet, blev udgivelsen af versionen, der oprindeligt var planlagt til 22. september 2016, udskudt flere gange: først blev datoen flyttet til 23. marts 2017 , derefter til 27. juli 2017 , og derefter til 21. juli 2017. September 2017 [25] [26] [27] .
Den seneste dato er blevet den officielle udgivelsesdato for versionen [28] .
Liste over innovationerUdgivelsesdato: 20. marts 2018 [38] .
Liste over innovationerDen officielle delvise liste over funktioner og udgivelsesplan er placeret på OpenJDK-webstedet .
Den officielle delvise liste over funktioner og udgivelsesplan er placeret på OpenJDK-webstedet . Udgivelsesdatoen er den 25. september 2018.
Liste over innovationerInden for Java er der flere store familier af teknologier:
Microsoft har udviklet sin egen JVM- implementering kaldet Microsoft Java Virtual Machine.(MSJVM) [58] , som var inkluderet i forskellige styresystemer startende med Windows 98 (også inkluderet i Internet Explorer fra version 3 og nyere, hvilket gjorde det muligt at bruge MSJVM i Windows 95 og Windows NT 4 efter installation af IE3+ på disse OS'er).
MSJVM havde betydelige forskelle fra Sun Java, og bryder på mange måder det grundlæggende koncept for portabilitet af programmer mellem forskellige platforme:
Javas tætte integration med DCOM og Win32 har sat spørgsmålstegn ved sprogets cross-platform paradigme. Efterfølgende var dette årsagen til retssager fra Sun Microsystems mod Microsoft. Retten tog Sun Microsystems side. I sidste ende blev der indgået en aftale mellem de to virksomheder om muligheden for at forlænge perioden med officiel støtte til brugere af det ikke-standardiserede Microsoft JVM indtil udgangen af 2007 [58] .
I 2005 introducerede Microsoft et Java-lignende sprog J# til .NET -platformen , som ikke svarer til den officielle specifikation af Java-sproget og blev efterfølgende udelukket fra Microsoft Visual Studios standardudviklerværktøj , startende med Visual Studio 2008 [59] .
Java-sproget bruges aktivt til at skabe mobilapplikationer til Android-operativsystemet. Samtidig kompileres programmer til ikke-standard bytekode til brug af deres Dalvik virtuelle maskine (startende med Android 5.0 Lollipop er den virtuelle maskine blevet erstattet af ART ). Til en sådan kompilering bruges et yderligere værktøj, nemlig Android SDK ( Software Development Kit ), udviklet af Google .
Applikationsudvikling kan udføres i Android Studio , NetBeans , Eclipse ved hjælp af Android Development Tools (ADT) plugin eller IntelliJ IDEA . JDK-versionen skal være 5.0 eller nyere.
Den 8. december 2014 blev Android Studio anerkendt af Google som det officielle udviklingsmiljø for Android OS.
Følgende vellykkede projekter er blevet implementeret ved hjælp af Java ( J2EE ) teknologier: RuneScape , Amazon [60] [61] , eBay [62] [63] , LinkedIn [64] , Yahoo! [65] .
Følgende virksomheder fokuserer hovedsageligt på Java ( J2EE- ) teknologier: SAP , IBM , Oracle . Især Oracle Database DBMS inkluderer en JVM som sin komponent, som giver mulighed for direkte at programmere DBMS i Java-sproget, herunder for eksempel lagrede procedurer [66] .
Programmer skrevet i Java har ry for at være langsommere og optage mere RAM end dem skrevet i C [6] . Udførelseshastigheden af programmer skrevet på Java-sproget blev dog væsentligt forbedret med udgivelsen i 1997-1998 af den såkaldte JIT-compiler i version 1.1, foruden andre sprogfunktioner til at understøtte bedre kodeanalyse (såsom indre klasser, klasse StringBuffer[doc 5] , forenklede logiske beregninger og så videre). Derudover er den virtuelle Java-maskine blevet optimeret - siden 2000 er den virtuelle HotSpot -maskine blevet brugt til dette . Fra februar 2012 er Java 7-kode cirka 1,8 gange langsommere end C-kode [67] .
Nogle platforme tilbyder hardwareudførelsesunderstøttelse til Java [68] . For eksempel mikrocontrollere, der kører Java-kode i hardware i stedet for en software-JVM, og ARM-baserede processorer, der understøtter Java-bytekode-udførelse via Jazelle-indstillingen.
Der er kun 8 primitive (skalære, simple) typer i Java : boolean, byte, char, short, int, long, float, double. Der er også en ekstra niende primitiv type - voidmen variabler og felter af denne type kan ikke erklæres i koden, og selve typen bruges kun til at beskrive den klasse, der svarer til den, til brug i refleksion : for eksempel ved at bruge Void[dok. 6] kan du finde ud af, om en bestemt metode er af typen void: Hello.class.getMethod("main", String[].class).getReturnType() == Void.TYPE.
Længderne og værdiintervallerne for primitive typer er defineret af standarden, ikke af implementeringen, og er angivet i tabellen. Char-typen blev lavet to-byte for bekvemmelighed ved lokalisering (et af Javas ideologiske principper): da standarden blev dannet, eksisterede Unicode -16 allerede, men ikke Unicode-32. Da der ikke var nogen enkelt-byte-type tilbage som et resultat, blev en ny type-byte tilføjet, og i Java, i modsætning til andre sprog, er den ikke usigneret. Typerne floatog doublekan have specielle værdier og "ikke et tal" ( NaN ). For dobbelttypen er de betegnet med , , ; for type - det samme, men med et præfiks i stedet for . De minimums- og maksimumværdier, der accepteres af og typerne , er også standardiserede. Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITYDouble.NaNfloatFloatDoublefloatdouble
Type | Længde (i bytes) | Område eller sæt af værdier |
---|---|---|
boolesk | 1 i arrays, 4 i variabler [69] | sandt falsk |
byte | en | −128..127 |
char | 2 | 0..2 16 −1 eller 0..65535 |
kort | 2 | −2 15 ..2 15 −1 eller −32768..32767 |
int | fire | −2 31 ..2 31 −1, eller −2147483648..2147483647 |
lang | otte | −2 63 ..2 63 −1, eller cirka −9,2 10 18 ..9.2 10 18 |
flyde | fire | -(2-2 −23 ) 2 127 ..(2-2 −23 ) 2 127 , eller cirka −3,4 10 38 ..3.4 10 38 , og også , , NaN |
dobbelt | otte | -(2-2 −52 ) 2 1023 ..(2-2 −52 ) 2 1023 , eller cirka −1,8 10 308 ..1.8 10 308 , samt , , NaN |
En sådan rigid standardisering var nødvendig for at gøre sproget platform-uafhængigt, hvilket er et af de ideologiske krav til Java. Der er dog stadig et lille problem med platformsuafhængighed. Nogle processorer bruger 10-byte registre til mellemlagring af resultater eller forbedrer nøjagtigheden af beregninger på andre måder. For at gøre Java så interoperabelt som muligt mellem forskellige systemer, var enhver måde at forbedre beregningernes nøjagtighed forbudt i tidlige versioner. Dette resulterede dog i langsommere ydeevne. Det viste sig, at få mennesker har brug for forringelsen af nøjagtigheden af hensyn til platformens uafhængighed, især hvis de skal betale for det ved at bremse programmernes arbejde. Efter adskillige protester blev dette forbud annulleret, men nøgleordet blev tilføjet strictfp, som forbyder øget nøjagtighed.
Transformationer i matematiske operationerJava-sproget har følgende regler:
Denne metode til implicit konvertering af indbyggede typer falder fuldstændig sammen med typekonvertering i C / C++ [70] .
Java-sproget har kun dynamisk oprettede objekter. Objekttypevariabler og objekter i Java er helt forskellige enheder. Variabler af en objekttype er referencer , det vil sige analoger af pointere til dynamisk oprettede objekter. Dette understreges af syntaksen for deklarationen af variable. Så C++-koden kan se sådan ud:
dobbelt a [ 10 ][ 20 ] ; foo b ( 30 );Men det samme i Java vil se meget anderledes ud:
dobbelt [][] a = ny dobbelt [ 10 ][ 20 ] ; Foo b = ny Foo ( 30 );Under tildelinger, videregivelse til underrutiner og sammenligninger opfører objektvariable sig som pointere, det vil sige, at adresser på objekter tildeles, kopieres og sammenlignes. Og når man får adgang til datafelter eller metoder for et objekt med en objektvariabel, kræves ingen specielle dereferencehandlinger - adgangen udføres, som om objektvariablen var selve objektet.
Objektvariabler er variabler af enhver type, undtagen primitive. Der er ingen eksplicitte pointer i Java. I modsætning til pointere i C, C++ og andre programmeringssprog er referencer i Java meget sikre på grund af strenge begrænsninger for deres brug.
Takket være sådanne specielt indførte begrænsninger er direkte hukommelsesmanipulation på niveau med fysiske adresser umulig i Java (selvom værdien af referencen, der peger på ingenting, er defineret: null).
Hvis der er behov for en pointer til en primitiv type, bruges wrapperklasser af primitive typer: Boolean, Byte, Character, Short, Integer, Long, Float, Double.
Duplikere links og kloningVed tildeling kopieres objektet ikke, da objektvariabler er referencevariabler. Så hvis du skriver
Foo foo , bar ; ... bar = foo ;så vil adressen blive kopieret fra variabel footil variabel bar. Det vil sige, fooog barvil pege på det samme hukommelsesområde, det vil sige på det samme objekt; forsøg på at ændre felterne i det objekt, der refereres til af variablen foo, vil ændre det objekt, der refereres til af variablen barog omvendt. Hvis det er nødvendigt at få blot en kopi mere af det originale objekt, bruger de enten en metode (medlemsfunktion, i C++ terminologi) clone (), der opretter en kopi af objektet, eller (mindre ofte) en kopikonstruktør ( konstruktører i Java kan ikke være virtuel, så en forekomst af en efterkommerklasse vil være forkert kopieret af konstruktøren af forfaderklassen; klonemetoden påkalder den ønskede konstruktør og omgår derved denne begrænsning).
Metode clone()[dok. 7] kræver en klasse for at implementere en grænseflade Cloneable[dok. 8] . Hvis en klasse implementerer grænsefladen Cloneable, clone()kopierer den som standard alle felter ( overfladisk kopi ). Hvis du vil klone felter (såvel som deres felter og så videre) i stedet for at kopiere, skal du tilsidesætte clone(). At definere og bruge en metode clone()er ofte en ikke-triviel opgave [72] .
Variabel initialiseringAlle variabler kræver enten en eksplicit definition eller udfyldes automatisk med nuller (0, null, false). Således forsvinder heisenbugs forbundet med utilsigtet brug af uinitialiseret hukommelse, karakteristisk for lavniveausprog som C .
AffaldsopsamlingI Java-sproget er det ikke muligt eksplicit at slette et objekt fra hukommelsen - i stedet implementeres garbage collection . Et traditionelt trick til at give skraldeopsamleren et "tip" til at deallokere hukommelse er at sætte en variabel til null null, hvilket kan være effektivt, når du skal deallokere et objekt, der ikke længere er nødvendigt, og som refereres til i et objekt med lang levetid [73 ] . Dette betyder dog ikke, at det objekt, der erstattes af værdien null, helt sikkert og øjeblikkeligt vil blive slettet, men der er en garanti for, at dette objekt vil blive slettet i fremtiden. Denne teknik fjerner kun referencen til objektet, det vil sige frigør markøren fra objektet i hukommelsen. I dette tilfælde skal man huske på, at objektet ikke vil blive slettet af skraldeopsamleren, så længe mindst én reference fra de anvendte variabler eller objekter peger på det. Der er også metoder til at starte en tvungen affaldsindsamling, men de er ikke garanteret at blive kaldt af runtime og anbefales ikke til normal brug.
Java er ikke et proceduresprog: enhver funktion kan kun eksistere inden for en klasse. Dette understreges af Java-sprogets terminologi, hvor der ikke findes begreber om "funktion" eller "medlemsfunktion" ( engelsk member function ), men kun en metode . Standardfunktioner er også blevet til metoder. For eksempel er der ingen funktion i Java , men der er en sin()klassemetode Math.sin()( Mathder indeholder ud over sin()metoder cos(), exp(), sqrt(), abs()og mange andre). Konstruktører i Java betragtes ikke som metoder. Der er ingen destruktorer i Java, og en metode finalize()bør på ingen måde betragtes som analog med en destruktor.
KonstruktørerEn konstruktør er en speciel metode, der nødvendigvis kaldes, når et nyt objekt oprettes, det vil sige, at et objekt (en forekomst af en klasse) ikke kan oprettes uden at kalde klassekonstruktøren. Det er ikke altid praktisk at initialisere alle variabler i en klasse, når den instansieres, så instansvariable er ofte erklæret inde i en konstruktørs krop, men initialiseres som konstruktørargumenter, når klassen instansieres. Nogle gange er det nemmere at få nogle værdier oprettet som standard, når objektet er oprettet. I dette tilfælde deklareres og initialiseres variabler inde i konstruktørens krop.
En konstruktør initialiserer et objekt direkte på oprettelsestidspunktet. Navnet på konstruktøren er det samme som navnet på klassen, inklusive store og små bogstaver, og syntaksen for en konstruktør svarer til en metode uden returværdi.
privat int Cat (); // sådan ser metoden ved navn Cat ud som Cat (); // sådan ser Cat-klassekonstruktøren udI modsætning til en metode returnerer en konstruktør aldrig noget.
En konstruktør definerer de handlinger, der skal udføres, når et objekt i en klasse oprettes og er en vigtig del af en klasse. Som regel forsøger programmører eksplicit at specificere en konstruktør. Hvis der ikke er nogen eksplicit konstruktør, vil Java automatisk oprette en (tom) til standardbrug.
Som et eksempel kan du overveje en klasse Box, der repræsenterer en beskrivelse af en boks. Klassekonstruktøren vil simpelthen indstille de indledende dimensioner for boksen.
classBox { int width ; _ // kassebredde int højde ; // kassehøjde int dybde ; // kassedybde // Constructor Box ( int a , int b ) { width = a ; højde = b ; dybde = 10 ; } // beregne rumfanget af boksen int getVolume () { return width * height * depth ; } } Statiske metoder og felterJava (såvel som C++) bruger statiske felter og statiske metoder ( statisk metode - i programmeringsteori kaldes de også klassemetoder), som specificeres ved hjælp af nøgleordet . Statiske felter (klassevariable) har samme betydning som i C++: hvert sådant felt er klassens egenskab, så du behøver ikke oprette forekomster af den tilsvarende klasse for at få adgang til statiske felter. static
For eksempel kan matematiske funktioner implementeret i klassen Math[dok. 9] er blot statiske metoder i denne klasse. Derfor kan de kaldes direkte fra klassen uden at oprette en forekomst af den, for eksempel:
dobbelt x = matematik . synd ( 1 );Det er forbudt at oprette en forekomst af en statisk klasse ved at bruge en privat konstruktør. For eksempel vil oprettelse af en forekomst af en klasse Mathresultere i en kompileringsfejl:
Math m = new Math (); // Fejl: Math() har privat adgang i java.lang.Math double x = m . synd ( 1 ); // Objektet ville ikke have en sin metode, da det er statiskDa statiske metoder eksisterer uafhængigt af objekter (forekomster af en klasse), har de ikke adgang til almindelige (ikke-statiske) felter og metoder i den givne klasse. Især, når du implementerer en statisk metode, MÅ du IKKE bruge identifikatoren this.
Den statiske importfunktion giver dig mulighed for at kalde statiske funktioner og konstanter uden at angive en klasse. Eksempel uden statisk import:
dobbelt x = matematik . sin ( Math . tan ( Math . sqrt ( y )) + Math . floor ( 24.5 )) + Math . cos ( 42 * Matematik . PI );Det samme eksempel, men med statisk import:
importer statisk java.lang.Math.* ; ... dobbelt x = sin ( tan ( sqrt ( y )) + floor ( 24,5 )) + cos ( 42 * PI ); Afslutning (endelig)Nøgleordet final(endelig) har forskellige betydninger, når det beskriver et felt, metode eller klasse.
I Java er metoder, der ikke udtrykkeligt er erklæret som static, finaleller private, virtuelle i C++-terminologi: kalder en metode, der er defineret forskelligt i basis- og arveklasser, udføres altid en runtime-kontrol.
En abstrakt metode ( modifier abstract) i Java er en metode, der har parametre og en returtype, men ingen krop. En abstrakt metode er defineret i afledte klasser. Analogen til en abstrakt metode i C++ er en ren virtuel funktion. For at en klasse skal kunne beskrive abstrakte metoder, skal selve klassen også erklæres abstrakt. Abstrakte klasseobjekter kan ikke oprettes.
GrænsefladerDen højeste grad af abstraktion i Java er grænsefladen (modifier interface). Grænsefladen indeholder for det meste abstrakte metoder, der har et offentligt adgangsniveau: deskriptorer abstractog publicer ikke engang nødvendige for dem. Men siden Java 8 og 9 er muligheden for at bruge i grænseflader blevet introduceret.
- Java 8: statiske ( static) metoder og standardmetoder ( default);
- Java 9: metoder med adgangsniveau private.
Disse metoder indeholder en krop, hvilket betyder, at de ikke er abstrakte, men i en specifik implementering af grænsefladen kan default-metoder tilsidesættes.
En grænseflade i Java betragtes ikke som en klasse, selvom den i virkeligheden er en fuldstændig abstrakt klasse. En klasse kan arve/ udvide ( extends) en anden klasse eller implementere ( implements) en grænseflade. En grænseflade kan også arve/udvide ( extends) en anden grænseflade.
I Java kan en klasse ikke arve fra mere end én klasse, men den kan implementere flere grænseflader. Multipel nedarvning af grænseflader er ikke forbudt, det vil sige, at en grænseflade kan nedarves fra flere.
Interfaces kan bruges som metodeparametertyper. Grænseflader kan ikke instansieres.
MarkørgrænsefladerJava har grænseflader, der ikke indeholder metoder til implementering, men håndteres på en særlig måde af JVM: Cloneable, Serializable, RandomAccess, Remote.
Skabeloner i Java (generisk)Startende med Java 5.0 dukkede en generisk programmeringsmekanisme op i sproget - skabeloner, der udadtil er tæt på C++-skabeloner. Ved at bruge en speciel syntaks i beskrivelsen af klasser og metoder kan du angive typeparametre, der kan bruges inde i beskrivelsen som felttyper, parametre og returværdier for metoder.
// Generisk klasseerklæring klasse GenericClass < E > { E getFirst () { ... } void add ( E obj ) { ... } } // Brug af en generisk klasse i koden GenericClass < String > obj = new GenericClass <> (); obj . tilføje ( "qwerty" ); Streng p = obj . getFirst ();Generisk erklæring af klasser, grænseflader og metoder er tilladt. Derudover understøtter syntaksen begrænsede typeparameterdeklarationer: Angivelse af en typekonstruktion i deklarationen <T extends A & B & C...>kræver, at typeparameteren T implementerer grænsefladerne A, B, C og så videre.
I modsætning til C#-skabeloner understøttes Java-skabeloner ikke af runtime - compileren opretter blot bytekode, hvori der ikke længere er skabeloner. Implementeringen af skabeloner i Java er fundamentalt forskellig fra implementeringen af lignende mekanismer i C++: compileren genererer ikke en separat variant af en klasse eller skabelonmetode for hvert tilfælde af brug af en skabelon, men opretter blot en enkelt bytekodeimplementering, der indeholder de nødvendige typetjek og ombygninger. Dette fører til en række restriktioner for brugen af skabeloner i Java-programmer.
Kontrollerer for klassemedlemskabI Java kan du eksplicit kontrollere, hvilken klasse et objekt tilhører. Udtrykket foo instanceof Fooer det samme, truehvis objektet footilhører en klasse Fooeller dens efterkommer, eller implementerer en grænseflade Foo(eller mere generelt, arver en klasse, der implementerer en grænseflade, der arver Foo).
Endvidere er funktionen getClass()[dok. 10] , defineret for alle objekter, producerer et objekt af typen Class<?>. For hver klasse oprettes højst ét objekt af typen, der beskriver den Class, så disse objekter kan sammenlignes. Så for eksempel vil foo.getClass() == bar.getClass()det være sandt, hvis objekterne fooog bartilhører samme klasse.
Derudover kan en genstand af Class<?>enhver type opnås på denne måde: Integer.class, Object.class.
Direkte sammenligning af klasser er ikke altid det bedste middel til at kontrollere for klassemedlemskab. Ofte bruges en funktion i stedet for isAssignableFrom(). Denne funktion er defineret på et typeobjekt Classog tager et typeobjekt som Class<?>en parameter. Således vil opkaldet Foo.class.isAssignableFrom(Bar.class)vende tilbage, truehvis det Fooer en forfader til klassen Bar. Da alle objekter er efterkommere af typen Object, vil opkaldet Object.class.isAssignableFrom()altid vende tilbage true.
I forbindelse med de nævnte funktioner af typeobjektet Class, vil funktionerne isInstance[dok. 11] (svarende til instanceof), samt cast()(konverterer parameteren til et objekt af den valgte klasse).
Fejlhåndtering i Java ligner fejlhåndtering i C++ bortset fra behovet for en finally. Denne forskel skyldes det faktum, at Java ikke kan overholde begrebet RAII på grund af tilstedeværelsen af en skraldeopsamler, og den automatiske frigivelse af ressourcer i destruktoren kan forekomme i en uforudsigelig rækkefølge med vilkårlige intervaller.
Fejlhåndtering udføres ved hjælp af operatorerne try, catchog finally. Den kastede fejl er beskrevet af et objekt af en bestemt klasse, der arver fra Throwable[dok. 12] og svarende til fejltypen. Inde i blokken tryer kode, der kan give en undtagelse, og blokken catchfanger de typer fejl, der er angivet af programmøren. I dette tilfælde kan du angive mere end én blok catchfor at håndtere forskellige fejlklasser, eller multi-catch for at håndtere flere fejl. Blokken er valgfri, men hvis den er til stede, udføres den uanset forekomsten af en fejl og er beregnet til at frigive de ressourcer, der er finallyallokeret under driften af blokken .try
Siden Java 7 har grænsefladen AutoCloseable[dok. 13] , som giver dig mulighed for at implementere klasser, der automatisk frigiver ressourcer. Objekter af sådanne klasser skal oprettes i parentes før try. Et simpelt eksempel på automatisk ressourcetildeling er at læse indholdet af en fil:
importer java.io.* ; offentlig klasse Main { public static void main ( String [] args ) kaster IOException { if ( args . længde < 2 ) { System . fejl . println ( "Intet filnavn angivet." ); returnere ; } String filnavn = args [ 1 ] ; // Den åbnede fil lukkes automatisk ved en fejl prøv ( BufferedReader reader = new BufferedReader ( new FileReader ( filnavn ))) { String line ; for ( int n = 1 ; ( linje = læser . readLine ()) != null ; ++ n ) { System . ud . println ( n + ": " + linje ); } } catch ( FileNotFoundException e ) { System . fejl . println ( "Den angivne fil blev ikke fundet." ); } // langt om længe { // reader.close(); // automatisk ressourcelukning // } } }Java overholder konceptet med obligatorisk specificering af de fejlklasser, som en metode kan kaste. Dette gøres ved hjælp af et nøgleord throwsefter metodebeskrivelsen. Hvis metoden ikke specificerer en undtagelsesklasse (eller dens forfader), der kan kastes fra metoden, vil dette forårsage en kompileringsfejl. Konceptet skulle gøre koden selvdokumenterende, hvilket angiver, hvilke undtagelser en bestemt metode kan give, men i praksis retfærdiggør det sjældent sig selv, fordi en programmør på grund af forskellige omstændigheder kan angive en klasse som en undtagelse, der skal kastes Exceptioneller omslutte problematisk . dele af en metode i en blok try... catchat ignorere individuelle fejl, eller - i blokken try... at finallyskjule alle mulige fejl. Ulempen ved konceptet er også, at programmøren selv skal definere og foreskrive de undtagelser, som metoden kan kaste [74] .
Ideen med navnerum er inkorporeret i Java-pakker .
Navnet på Java-pakken er latin (små og store bogstaver) med tal (ikke det første i linjen) og en understregning (ikke den første og ikke den sidste), som ikke er sproginstruktioner (bemærk if, null), adskilt af prikker .
Eksempler på korrekte navne:
Eksempler på forkerte navne:
Pakker indeholder klasser, grænseflader, opregninger, anmærkninger (osv.), hvis navne er latinske (små og store bogstaver) med tal (ikke det første i en linje). Der kan kun være én offentlig klasse, grænseflade (osv.) i én fil. Navnet på den offentlige klasse, interface (osv.) i filen skal matche navnet på filen. Hver klasse har sit eget navneområde for funktioner, variabler og underklasser, undergrænseflader (osv.), og du kan få en underklasse af en klasse ved at bruge OuterClass.InnerClass, eller du kan bruge OuterClass$InnerClass, så det anbefales ikke at bruge dollarsymbolet i klassenavnet.
Programkode "Hej, verden!" .
klasse hej verden { public static void main ( String [] args ) { System . ud . println ( "Hej verden!" ); } } Et eksempel på brug af generika import java.util.List ; import java.util.ArrayList ; public class Sample { public static void main ( String [] args ) { // Opret et objekt fra en skabelon. List < String > strings = new ArrayList <> (); strenge . add ( "Hej" ); strenge . tilføje ( "verden" ); strenge . tilføje ( "!" ); for ( var streng : strenge ) { System . ud . print ( streng + " " ); } } } Et eksempel på brug af refleksion import java.lang.reflect.Field ; import java.lang.reflect.Method ; klasse TestClass { privat int værdi ; public int getValue () { return value ; } public void setValue ( int valueIn ) { this . værdi = værdiIn ; } } public class Main { public static void main ( String [] args ) { var testClass = new TestClass (); for ( var field : testClass . getClass (). getDeclaredFields ()) { System . ud . printf ( "navn:%s, skriv:%s \n" , felt .getName (), felt .getType (). getCanonicalName ( ) ); } for ( var metode : testClass . getClass (). getDeclaredMethods ()) { System . ud . printf ( "navn:%s, returtype:%s \n" , metode .getName (), metode .getReturnType (). getCanonicalName ( ) ); } } } Anmærkningseksempel import java.lang.annotation.ElementType ; import java.lang.annotation.Retention ; import java.lang.annotation.RetentionPolicy ; importer java.lang.annotation.Target ; @Retention ( RetentionPolicy . RUNTIME ) @Target ( ElementType . TYPE ) public @interface MyAnnotation { offentlig boolesk værdi () default false ; } @MyAnnotation ( værdi = sand ) public class TestClass { } public class Main { public static void main ( String [] args ) { var testClass = new TestClass (); var myAnnotation = testClass . getClass (). getAnnotation ( MyAnnotation . klasse ); if ( myAnnotation != null ) { System . ud . printf ( "værdi:%s \n" , minAnnotation . værdi ()); } } } ![]() | ||||
---|---|---|---|---|
Tematiske steder | ||||
Ordbøger og encyklopædier | ||||
|
Java | |
---|---|
Platforme | |
Sun Technologies | |
Nøgle tredjepartsteknologier | |
Historie |
|
Sprogegenskaber | |
Scripting sprog |
|
Java konferencer |
|
Programmeringssprog | |
---|---|
|