Java | |
---|---|
Språkklass | multiparadigm programmeringsspråk , JVM-språk och programvara |
Framträdde i | 1995 |
Författare | James Gosling och Sun Microsystems |
Utvecklaren | Sun Microsystems och Oracle |
Filtillägg _ | .java, .class, .jar, .jadeller.jmod |
Släpp | Java SE 18.0.2.1 ( 18 augusti 2022 ) |
Blivit påverkad | C++ , C , Ada , Simula 67 , Smalltalk , Objective-C , Object Pascal , Oberon , Eiffel , Modula-3 , Mesa , Simula , C# , UCSD Pascal , wrapper , Variabel funktion , Java-anteckning , Nicklaus Wirth , Patrick Naughton [d] och foreach |
Licens | GNU GPL [1] |
Hemsida | oracle.com/ru/java/ |
Mediafiler på Wikimedia Commons |
Java [ca. 1] är ett starkt skrivet objektorienterat programmeringsspråk för allmänt bruk utvecklat av Sun Microsystems (senare förvärvat av Oracle ). Utvecklingen drivs av en community organiserad genom Java Community Process ; språket och den underliggande tekniken som implementerar det distribueras under GPL-licensen . Varumärkesrättigheter ägs av Oracle Corporation .
Java-applikationer översätts vanligtvis till speciell bytekod , så de kan köras på vilken datorarkitektur som helst för vilken det finns en implementering av Java Virtual Machine . Det officiella släppdatumet är den 23 maj 1995. Det rankas högt i programmeringsspråkets popularitetsrankning (2:a plats i IEEE Spectrum (2020) [2] och TIOBE (2021) [3] rankningar ).
Språket hette ursprungligen Oak ("Oak"), utvecklat av James Gosling för programmering av konsumentelektronik. Eftersom ett språk med det namnet redan fanns, döptes Oak om till Java [4] . Uppkallad efter kaffemärket Java, som i sin tur fick namnet på ön med samma namn ( Java ), så språkets officiella emblem visar en kopp varmt kaffe. Det finns en annan version av ursprunget till språkets namn, associerad med en anspelning på en kaffemaskin som ett exempel på en hushållsenhet för programmering som språket ursprungligen skapades. I enlighet med etymologi, i ryskspråkig litteratur från slutet av 1900-talet till de första åren av det tjugoförsta århundradet, översattes språkets namn ofta till Java och transkriberades inte.
Som ett resultat av projektet såg världen en fundamentalt ny enhet, Star7 pocket persondator [5] , som var före sin tid med mer än 10 år, men på grund av den höga kostnaden på $ 50, kunde den inte revolutionera teknikens värld och glömdes bort.
Star7-enheten var inte populär, till skillnad från programmeringsspråket Java och dess miljö. Nästa steg i språkets liv var utvecklingen av interaktiv tv. 1994 stod det klart att interaktiv tv var ett misstag.
Sedan mitten av 1990-talet har språket blivit flitigt använt för att skriva klientapplikationer och servermjukvara . Samtidigt fick teknologin för Java-applets , grafiska Java-applikationer inbäddade i webbsidor, en viss popularitet; Med tillkomsten av dynamiska webbsidor på 2000-talet blev tekniken mindre utbredd.
Webbutveckling använder Spring Framework ; Javadoc- verktyget används för dokumentation .
Java -program översätts till Java bytecode , som exekveras av Java Virtual Machine (JVM), ett program som bearbetar bytekod och skickar instruktioner till hårdvaran som tolk .
Fördelen med detta sätt att köra program är det fullständiga oberoendet av bytekoden från operativsystemet och hårdvaran , vilket gör att du kan köra Java-applikationer på vilken enhet som helst för vilken det finns en motsvarande virtuell maskin. En annan viktig egenskap hos Java-tekniken är ett flexibelt säkerhetssystem, där exekveringen av programmet helt kontrolleras av den virtuella maskinen. Alla åtgärder som överskrider programmets inställda behörigheter (som att försöka obehörig åtkomst till data eller ansluta till en annan dator) orsakar en omedelbar avbrytning.
Ofta inkluderar nackdelarna med konceptet virtuella maskiner prestandaförsämring. Ett antal förbättringar ökade hastigheten på Java-program något:
Enligt sajten shootout.alioth.debian.org, för sju olika uppgifter, är körtiden i Java i genomsnitt en och en halv till två gånger längre än för C/C++, i vissa fall är Java snabbare, och i vissa fall är det 7 gånger långsammare [ 6] . Å andra sidan, för de flesta av dem var minnesförbrukningen för en Java-maskin 10 till 30 gånger större än för ett C/C++-program. Anmärkningsvärt är också en studie gjord av Google , enligt vilken det finns en betydligt lägre prestanda och högre minnesförbrukning i testfall i Java jämfört med liknande program i C ++ [7] [8] [9] .
Idéerna bakom konceptet och olika implementeringar av den virtuella Java-maskinmiljön har inspirerat många entusiaster att utöka listan över språk som kan användas för att skapa program som körs på en virtuell maskin [10] . Dessa idéer uttrycks också i specifikationen Common Language Infrastructure ( CLI ) som stödde Microsofts .NET- plattform .
Java-utvecklingen började 1990, den första officiella versionen - Java 1.0 - släpptes först den 21 januari 1996.
Den andra versionen släpptes den 19 februari 1997 [11] .
Utgivningsdatum 8 december 1998 [12] . Kodnamn Lekplats. I det här fallet finns det förvirring. Böcker har publicerats, till exempel Beginning Java 2 av Ivor Horton (mars 1999), faktiskt på J2SE 1.2 (tidigare kallad Java 2). Än i dag publiceras dock sådana böcker, till exempel: H. M. Deitel, P. J. Deitel, S. I. Santry. Java Programming Technologies 2. Distribuerade applikationer (2011).
Vid en tidpunkt då Java 2 är känt för att ha ersatts historiskt av efterföljande utgåvor, är sådana boktitlar vilseledande när det gäller vilken version av Java de faktiskt skrivs om. Om J2SE 1.2 anses vara Java 2, men författarna till Java 2-böcker accepterar JDK 7, leder detta till fullständig förvirring.
Utgivningsdatum 8 maj 2000. Kodnamn Kestrel.
Utgivningsdatum 6 februari 2002. Kodnamn Merlin.
Java 5.0-specifikationen släpptes den 30 september 2004, med kodnamnet Tiger. Sedan denna version har den officiella indexeringen ändrats, istället för Java 1.5 är det mer korrekt att kalla Java 5.0. Suns interna indexering förblir densamma - 1,x. Mindre ändringar ingår nu utan att ändra indexering, för detta används ordet "Uppdatera" eller bokstaven "u", till exempel Java Development Kit 5.0 Update 22. Det antas att uppdateringar kan innehålla både buggfixar och små tillägg till API, JVM.
I den här versionen har utvecklarna gjort ett antal grundläggande tillägg till språket:
Versionen släpptes den 11 december 2006, med kodnamnet Mustang. Den officiella indexeringen har ändrats - istället för den förväntade 6.0 är versionen listad som 6. Mindre ändringar, som i Java 5.0, görs i vanliga versionsuppdateringar, till exempel Java Standard Edition Development Kit 6 Update 27. Följande ändringar har gjorts:
Utgivningsdatum 8 oktober 2013.
JavaFX 2.2 ingår i Java SE 7 uppdatering 6 [15] . Från version 11 levereras modulen separat från JDK [16] .
Utgivningsdatum 10 oktober 2013. Kodnamn Micro Edition.
Versionen släpptes den 28 juli 2011, kodnamnet Dolphin [17] . Den slutliga versionen av Java Standard Edition 7 inkluderade inte alla tidigare planerade ändringar. Enligt utvecklingsplanen (plan "B") [18] kommer inkluderingen av innovationer att delas upp i två delar: Java Standard Edition 7 (utan lambdakalkylen , Jigsaw-projektet och en del av förbättringarna av Coin-projektet [ 19] ) och Java Standard Edition 8 (alla övriga), planerade till slutet av 2012.
I den nya versionen, kallad Java Standard Edition 7 (Java Platform, Standard Edition 7), infördes flera innovationer, förutom att åtgärda ett stort antal fel. Så till exempel användes inte det proprietära JDK -paketet utan dess öppna implementering OpenJDK som referensimplementering av Java Standard Edition 7 , och lanseringen av den nya versionen av plattformen förbereddes i nära samarbete mellan Oracle- ingenjörer och medlemmar i globala Java-ekosystemet, JCP- kommittén (Java Community Process) och av OpenJDK . Alla Oracle-levererade Java Standard Edition 7-referensimplementeringsbinärer är byggda ovanpå OpenJDK- kodbasen , och själva referensimplementeringen är helt öppen källkod under GPLv2 -licensen med GNU ClassPath-undantag för att tillåta dynamisk länkning till proprietära produkter. Andra innovationer inkluderar integration av en uppsättning små Java-språkförbättringar utvecklade av Coin-projektet, lagt till stöd för dynamiskt typade programmeringsspråk som Ruby , Python och JavaScript , stöd för att ladda klasser efter URL , en uppdaterad XML - stack som inkluderar JAXP 1.4, JAXB 2.2a och JAX-WS 2.2 och andra [20] .
Under de 5 dagarna före lanseringen av Java Standard Edition 7 upptäcktes flera allvarliga buggar i hot loop-optimering, som är aktiverad som standard och får Java Virtual Machine att krascha. Oracle-specialister kunde inte fixa de hittade felen på så kort tid, men lovade att de skulle fixas i den andra uppdateringen (Java 7 Update 2) och delvis i den första [21] .
Lista över innovationerVersionen släpptes den 19 mars 2014. Kodnamn Octopus.
Lista över innovationerPå grund av svårigheter med att implementera det modulära systemet inom Jigsaw-projektet sköts releasen av versionen, som ursprungligen var planerad till 22 september 2016, flera gånger: först flyttades datumet till 23 mars 2017 , sedan till 27 juli 2017 , och sedan till 21 juli 2017. September 2017 [25] [26] [27] .
Det senaste datumet har blivit det officiella releasedatumet för versionen [28] .
Lista över innovationerReleasedatum: 20 mars 2018 [38] .
Lista över innovationerDen officiella partiella listan över funktioner och releaseplan finns på OpenJDK-webbplatsen .
Den officiella partiella listan över funktioner och releaseplan finns på OpenJDK-webbplatsen . Releasedatum är 25 september 2018.
Lista över innovationerInom Java finns det flera stora familjer av teknologier:
Microsoft har utvecklat sin egen JVM- implementering som kallas Microsoft Java Virtual Machine.(MSJVM) [58] , som ingick i olika operativsystem från och med Windows 98 (ingår även i Internet Explorer från version 3 och högre, vilket gjorde det möjligt att använda MSJVM i Windows 95 och Windows NT 4 efter installation av IE3+ på dessa OS).
MSJVM hade betydande skillnader från Sun Java, vilket på många sätt bröt det grundläggande konceptet för portabilitet av program mellan olika plattformar:
Javas snäva integration med DCOM och Win32 har ifrågasatt språkets plattformsoberoende paradigm. Senare var detta anledningen till stämningar från Sun Microsystems mot Microsoft. Domstolen ställde sig på Sun Microsystems sida. Till slut nåddes en överenskommelse mellan de två företagen om möjligheten att förlänga perioden för officiellt stöd för användare av icke-standardiserade Microsoft JVM till slutet av 2007 [58] .
2005 introducerade Microsoft ett Java-liknande språk J# för .NET -plattformen , som inte motsvarar den officiella specifikationen för Java-språket och som därefter uteslöts från Microsoft Visual Studios standardverktyg för utvecklare , med början i Visual Studio 2008 [59] .
Java-språket används aktivt för att skapa mobilapplikationer för Android-operativsystemet. Samtidigt kompileras program till icke-standardiserad bytekod för användning av deras Dalvik virtuella maskin (från och med Android 5.0 Lollipop har den virtuella maskinen ersatts av ART ). För sådan sammanställning används ytterligare ett verktyg, nämligen Android SDK ( Software Development Kit ), utvecklat av Google .
Applikationsutveckling kan göras i Android Studio , NetBeans , Eclipse med plugin-programmet Android Development Tools (ADT) eller IntelliJ IDEA . JDK-versionen måste vara 5.0 eller högre.
Den 8 december 2014 erkändes Android Studio av Google som den officiella utvecklingsmiljön för Android OS.
Följande framgångsrika projekt har implementerats med hjälp av Java ( J2EE )-tekniker: RuneScape , Amazon [60] [61] , eBay [62] [63] , LinkedIn [64] , Yahoo! [65] .
Följande företag fokuserar huvudsakligen på Java ( J2EE- )-teknologier: SAP , IBM , Oracle . I synnerhet inkluderar Oracle Database DBMS en JVM som sin komponent, som ger möjlighet att direkt programmera DBMS i Java-språket, inklusive till exempel lagrade procedurer [66] .
Program skrivna i Java har rykte om att vara långsammare och ta upp mer RAM än de som skrivs i C [6] . Exekveringshastigheten för program skrivna på Java-språket förbättrades dock avsevärt med lanseringen 1997-1998 av den så kallade JIT-kompilatorn i version 1.1, förutom andra språkfunktioner för att stödja bättre kodanalys (som inre klasser, klass StringBuffer[doc 5] , förenklade logiska beräkningar och så vidare). Dessutom har den virtuella Java-maskinen optimerats - sedan 2000 har den virtuella HotSpot -maskinen använts för detta . Från och med februari 2012 är Java 7-koden ungefär 1,8 gånger långsammare än C-koden [67] .
Vissa plattformar erbjuder hårdvaruexekveringsstöd för Java [68] . Till exempel mikrokontroller som kör Java-kod i hårdvara istället för en mjukvaru-JVM, och ARM-baserade processorer som stöder Java-bytekodexekvering via Jazelle-alternativet.
Det finns bara 8 primitiva (skalära, enkla) typer i Java : boolean, byte, char, short, int, long, float, double. Det finns också en extra nionde primitiv typ - voidmen variabler och fält av denna typ kan inte deklareras i koden, och själva typen används endast för att beskriva den klass som motsvarar den, för användning i reflektion : till exempel med hjälp av Void[dok. 6] kan du ta reda på om en viss metod är av typen void: Hello.class.getMethod("main", String[].class).getReturnType() == Void.TYPE.
Längden och värdeintervallen för primitiva typer definieras av standarden, inte av implementeringen, och listas i tabellen. Char-typen gjordes två-byte för lokaliseringsbekvämlighet (en av Javas ideologiska principer): när standarden bildades fanns redan Unicode -16, men inte Unicode-32. Eftersom det inte fanns någon enkelbytetyp kvar som ett resultat, lades en ny typbyte till, och i Java, till skillnad från andra språk, är den inte osignerad. Typerna floatoch doublekan ha speciella värden och "inte ett nummer" ( NaN ). För dubbeltypen betecknas de med , , ; för typ - samma, men med ett prefix istället för . Minimi- och maximivärdena som accepteras av och typerna är också standardiserade. Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITYDouble.NaNfloatFloatDoublefloatdouble
Sorts | Längd (i byte) | Område eller uppsättning värden |
---|---|---|
booleskt | 1 i arrayer, 4 i variabler [69] | sant falskt |
byte | ett | −128..127 |
röding | 2 | 0..2 16 −1, eller 0..65535 |
kort | 2 | −2 15 ..2 15 −1, eller −32768..32767 |
int | fyra | −2 31 ..2 31 −1, eller −2147483648..2147483647 |
lång | åtta | −2 63 ..2 63 −1, eller ungefär −9,2 10 18 ..9.2 10 18 |
flyta | fyra | -(2-2 −23 ) 2 127 ..(2-2 −23 ) 2 127 , eller ungefär −3,4 10 38 ..3.4 10 38 , och även , , NaN |
dubbel | åtta | -(2-2 −52 ) 2 1023 ..(2-2 −52 ) 2 1023 , eller ungefär −1,8 10 308 ..1.8 10 308 , samt , , NaN |
En sådan stel standardisering var nödvändig för att göra språkplattformsoberoende, vilket är ett av de ideologiska kraven för Java. Ett litet problem med plattformsoberoende kvarstår dock. Vissa processorer använder 10-byte register för mellanlagring av resultat eller förbättrar noggrannheten i beräkningar på andra sätt. För att göra Java så interoperabelt som möjligt mellan olika system var alla sätt att förbättra beräkningarnas noggrannhet förbjudna i tidiga versioner. Detta resulterade dock i långsammare prestanda. Det visade sig att få människor behöver försämringen av noggrannheten för plattformsoberoendes skull, särskilt om de måste betala för det genom att sakta ner programmets arbete. Efter många protester avbröts detta förbud, men nyckelordet lades till strictfp, vilket förbjuder ökad noggrannhet.
Transformationer i matematiska operationerJava-språket har följande regler:
Denna metod för implicit konvertering av inbyggda typer sammanfaller helt med typkonvertering i C / C++ [70] .
Java-språket har bara dynamiskt skapade objekt. Objekttypvariabler och objekt i Java är helt olika enheter. Variabler av en objekttyp är referenser , det vill säga analoger av pekare till dynamiskt skapade objekt. Detta understryks av syntaxen för deklarationen av variabler. Så C++-koden kan se ut så här:
dubbla a [ 10 ][ 20 ] ; foo b ( 30 );Men samma sak i Java kommer att se väldigt annorlunda ut:
dubbel [][] a = ny dubbel [ 10 ][ 20 ] ; Foo b = ny Foo ( 30 );Under tilldelningar, överföring till subrutiner och jämförelser beter sig objektvariabler som pekare, det vill säga adresser till objekt tilldelas, kopieras och jämförs. Och när man får åtkomst till datafält eller metoder för ett objekt med en objektvariabel krävs inga speciella referensoperationer – åtkomsten utförs som om objektvariabeln vore själva objektet.
Objektvariabler är variabler av vilken typ som helst, utom primitiva. Det finns inga explicita pekare i Java. Till skillnad från pekare i C, C++ och andra programmeringsspråk är referenser i Java mycket säkra på grund av strikta begränsningar för deras användning.
Tack vare sådana speciellt införda begränsningar är direkt minnesmanipulation på nivån av fysiska adresser omöjlig i Java (även om värdet på referensen som pekar mot ingenting är definierat: null).
Om en pekare till en primitiv typ behövs används omslagsklasser av primitiva typer: Boolean, Byte, Character, Short, Integer, Long, Float, Double.
Duplicera länkar och kloningVid tilldelning kopieras inte objektet, eftersom objektvariabler är referensvariabler. Så om du skriver
Foo foo , bar ; ... bar = foo ;då kommer adressen att kopieras från variabel footill variabel bar. Det vill säga, foooch barkommer att peka på samma minnesområde, det vill säga till samma objekt; Om du försöker ändra fälten för objektet som variabeln refererar till fookommer det att ändra objektet som variabeln refererar till baroch vice versa. Om det är nödvändigt att bara få en kopia till av originalobjektet använder de antingen en metod (medlemsfunktion, i C++-terminologi) clone ()som skapar en kopia av objektet, eller (mindre ofta) en kopiakonstruktor ( konstruktorer i Java kan inte vara virtuell, så en instans av en understigande klass kommer att vara felaktig kopierad av konstruktören för ancestor-klassen; klonmetoden anropar den önskade konstruktorn och kringgår därmed denna begränsning).
Metod clone()[dok. 7] kräver en klass för att implementera ett gränssnitt Cloneable[dok. 8] . Om en klass implementerar gränssnittet Cloneable, kopierar den som standard clone()alla fält ( grund kopia ). Om du vill klona fält (liksom deras fält, och så vidare) istället för att kopiera, måste du åsidosätta clone(). Att definiera och använda en metod clone()är ofta en icke-trivial uppgift [72] .
VariabelinitieringAlla variabler kräver antingen en explicit definition eller fylls automatiskt med nollor (0, null, false). Således försvinner heisenbugs associerade med oavsiktlig användning av oinitierat minne, karakteristiskt för lågnivåspråk som C .
SophämtningI Java-språket är det inte möjligt att explicit radera ett objekt från minnet - istället implementeras skräpinsamling . Ett traditionellt knep för att ge sopsamlaren ett "tips" för att avallokera minne är att sätta en variabel till null null, vilket kan vara effektivt när du behöver omallokera ett objekt som inte längre behövs och som refereras i ett långlivat objekt [73 ] . Detta betyder dock inte att objektet som ersätts av värdet nullsäkert och omedelbart kommer att raderas, men det finns en garanti för att detta objekt kommer att raderas i framtiden. Denna teknik tar bara bort referensen till objektet, det vill säga kopplar bort pekaren från objektet i minnet. I det här fallet bör man komma ihåg att objektet inte kommer att raderas av sopsamlaren så länge som minst en referens från de använda variablerna eller objekten pekar på det. Det finns också metoder för att initiera en påtvingad sophämtning, men de är inte garanterade att anropas av körtiden och rekommenderas inte för normal användning.
Java är inte ett procedurspråk: alla funktioner kan bara existera inom en klass. Detta understryks av Java-språkets terminologi, där det inte finns några begrepp om "funktion" eller "medlemsfunktion" ( engelska medlemfunktionen ), utan bara en metod . Standardfunktioner har också blivit metoder. Till exempel, i Java finns det ingen funktion , men det finns en sin()klassmetod ( Math.sin()som Mathinnehåller, förutom sin(), metoder cos(), exp(), sqrt(), abs()och många andra). Konstruktörer i Java betraktas inte som metoder. Det finns inga destruktörer i Java, och en metod finalize()bör inte på något sätt anses vara analog med en destruktor.
KonstruktörerEn konstruktor är en speciell metod som nödvändigtvis anropas när ett nytt objekt skapas, det vill säga ett objekt (en instans av en klass) kan inte skapas utan att anropa klasskonstruktorn. Det är inte alltid bekvämt att initiera alla variabler i en klass när den instansieras, så instansvariabler deklareras ofta inuti kroppen av en konstruktor, men initieras som konstruktorargument när klassen instansieras. Ibland är det lättare att få vissa värden skapade som standard när objektet skapas. I det här fallet deklareras och initieras variabler inuti konstruktorns kropp.
En konstruktör initierar ett objekt direkt vid skapandet. Namnet på konstruktorn är detsamma som namnet på klassen, inklusive skiftläge, och syntaxen för en konstruktor liknar den för en metod utan ett returvärde.
privat int Cat (); // så här ser metoden med namnet Cat ut som Cat (); // så här ser Cat-klasskonstruktören utTill skillnad från en metod returnerar en konstruktor aldrig något.
En konstruktor definierar de åtgärder som ska vidtas när ett objekt i en klass skapas och är en viktig del av en klass. Som regel försöker programmerare att explicit specificera en konstruktor. Om det inte finns någon explicit konstruktor kommer Java automatiskt att skapa en (tom) för standardanvändning.
Som ett exempel, betrakta en klass Boxsom representerar en beskrivning av en ruta. Klasskonstruktorn kommer helt enkelt att ställa in de initiala dimensionerna för rutan.
classBox { int width ; _ // box bredd int höjd ; // box höjd int djup ; // låddjup // Constructor Box ( int a , int b ) { width = a ; höjd = b ; djup = 10 ; } // beräkna volymen av rutan int getVolume () { return width * height * depth ; } } Statiska metoder och fältJava (liksom C++) använder statiska fält och statiska metoder ( statisk metod - i programmeringsteori kallas de även klassmetoder), som specificeras med nyckelordet . Statiska fält (klassvariabler) har samma betydelse som i C++: varje sådant fält är klassens egenskap, så du behöver inte skapa instanser av motsvarande klass för att komma åt statiska fält. static
Till exempel, matematiska funktioner implementerade i klassen Math[dok. 9] är bara statiska metoder i denna klass. Därför kan de anropas direkt från klassen utan att skapa en instans av den, till exempel:
dubbel x = matematik . synd ( 1 );Det är förbjudet att skapa en instans av en statisk klass med en privat konstruktor. Till exempel kommer att skapa en instans av en klass Mathatt resultera i ett kompileringsfel:
Math m = new Math (); // Fel: Math() har privat åtkomst i java.lang.Math double x = m . synd ( 1 ); // Objektet skulle inte ha en sinmetod, eftersom det är statisktEftersom statiska metoder existerar oberoende av objekt (instanser av en klass), har de inte tillgång till vanliga (icke-statiska) fält och metoder för den givna klassen. I synnerhet när du implementerar en statisk metod FÅR du INTE använda identifieraren this.
Den statiska importfunktionen låter dig anropa statiska funktioner och konstanter utan att ange en klass. Exempel utan statisk import:
dubbel x = matematik . sin ( Math . tan ( Math . sqrt ( y )) + Math . floor ( 24.5 )) + Math . cos ( 42 * Math . PI );Samma exempel, men med statisk import:
importera statisk java.lang.Math.* ; ... dubbel x = sin ( tan ( sqrt ( y )) + floor ( 24,5 )) + cos ( 42 * PI ); Slutförande (slutligt)Nyckelordet final(slutligt) har olika betydelser när det beskriver ett fält, en metod eller en klass.
I Java är metoder som inte uttryckligen deklareras som static, finaleller private, virtuella i C++-terminologi: anrop av en metod som definieras annorlunda i bas- och ärvningsklasser utför alltid en körtidskontroll.
En abstrakt metod ( modifier abstract) i Java är en metod som har parametrar och en returtyp, men ingen kropp. En abstrakt metod definieras i härledda klasser. Analogen till en abstrakt metod i C++ är en ren virtuell funktion. För att en klass ska kunna beskriva abstrakta metoder måste även själva klassen förklaras abstrakt. Abstrakta klassobjekt kan inte skapas.
GränssnittDen högsta graden av abstraktion i Java är gränssnittet (modifierare interface). Gränssnittet innehåller mestadels abstrakta metoder som har en allmän åtkomstnivå: deskriptorer abstractoch publicsom inte ens krävs för dem. Men sedan Java 8 och 9 har möjligheten att använda i gränssnitt introducerats.
- Java 8: statiska ( static) metoder och standardmetoder ( default);
- Java 9: metoder med åtkomstnivå private.
Dessa metoder innehåller en kropp, vilket betyder att de inte är abstrakta, men i en specifik implementering av gränssnittet kan default-metoder åsidosättas.
Ett gränssnitt i Java anses inte vara en klass, även om det i själva verket är en helt abstrakt klass. En klass kan ärva/ förlänga ( extends) en annan klass eller implementera ( implements) ett gränssnitt. Ett gränssnitt kan också ärva/förlänga ( extends) ett annat gränssnitt.
I Java kan en klass inte ärva från mer än en klass, men den kan implementera flera gränssnitt. Flera arv av gränssnitt är inte förbjudet, det vill säga ett gränssnitt kan ärvas från flera.
Gränssnitt kan användas som metodparametertyper. Gränssnitt kan inte instansieras.
MarkörgränssnittJava har gränssnitt som inte innehåller metoder för implementering, utan hanteras på ett speciellt sätt av JVM:en: Cloneable, Serializable, RandomAccess, Remote.
Mallar i Java (generics)Från och med Java 5.0 dök en generisk programmeringsmekanism upp i språket - mallar som utåt sett är nära C++-mallar. Med hjälp av en speciell syntax i beskrivningen av klasser och metoder kan du specificera typparametrar som kan användas i beskrivningen som typer av fält, parametrar och returvärden för metoder.
// Generic class declaration class GenericClass < E > { E getFirst () { ... } void add ( E obj ) { ... } } // Använda en generisk klass i koden GenericClass < String > obj = new GenericClass <> (); obj . add ( "qwerty" ); Sträng p = obj . getFirst ();Generisk deklaration av klasser, gränssnitt och metoder är tillåten. Dessutom stöder syntaxen begränsade typparameterdeklarationer: att specificera en typkonstruktion i deklarationen <T extends A & B & C...>kräver att typparametern T implementerar gränssnitten A, B, C och så vidare.
Till skillnad från C#-mallar stöds inte Java-mallar av runtime - kompilatorn skapar helt enkelt bytekod, där det inte finns några mallar längre. Implementeringen av mallar i Java skiljer sig fundamentalt från implementeringen av liknande mekanismer i C ++: kompilatorn genererar inte en separat variant av en klass eller mallmetod för varje fall av användning av en mall, utan skapar helt enkelt en enda bytekodimplementering som innehåller nödvändiga typkontroller och omvandlingar. Detta leder till ett antal restriktioner för användningen av mallar i Java-program.
Söker efter klassmedlemskapI Java kan du uttryckligen kontrollera vilken klass ett objekt tillhör. Uttrycket foo instanceof Fooär lika trueom objektet footillhör en klass Fooeller dess avkomling, eller implementerar ett gränssnitt Foo(eller, mer generellt, ärver en klass som implementerar ett gränssnitt som ärver Foo).
Vidare kan funktionen getClass()[dok. 10] , definierad för alla objekt, producerar ett objekt av typen Class<?>. För varje klass skapas högst ett objekt av typen som beskriver den Class, så dessa objekt kan jämföras. Så, till exempel, foo.getClass() == bar.getClass()kommer det att vara sant om objekten foooch bartillhör samma klass.
Dessutom kan ett objekt av Class<?>vilken typ som helst erhållas så här: Integer.class, Object.class.
Direkt jämförelse av klasser är inte alltid det bästa sättet att kontrollera klassmedlemskap. Ofta används istället en funktion isAssignableFrom(). Denna funktion är definierad på ett typobjekt Classoch tar ett typobjekt som Class<?>en parameter. Således kommer samtalet Foo.class.isAssignableFrom(Bar.class)att återkomma trueom det Fooär en förfader till klassen Bar. Eftersom alla objekt är ättlingar av typen Objectkommer anropet Object.class.isAssignableFrom()alltid att återkomma true.
Tillsammans med de nämnda funktionerna för typobjektet Class, funktionerna isInstance[dok. 11] (motsvarande instanceof), samt cast()(konverterar parametern till ett objekt av den valda klassen).
Felhantering i Java liknar felhantering i C++ förutom behovet av en finally. Denna skillnad beror på det faktum att Java inte kan följa konceptet med RAII på grund av närvaron av en sophämtare, och den automatiska frigöringen av resurser i förstöraren kan ske i en oförutsägbar ordning med godtyckliga intervall.
Felhantering utförs med hjälp av operatorerna try, catchoch finally. Det kastade felet beskrivs av ett objekt av en viss klass som ärver från Throwable[dok. 12] och som motsvarar typen av fel. Inuti blocket tryfinns kod som kan skapa ett undantag, och blocket catchfångar de typer av fel som specificeras av programmeraren. I det här fallet kan du ange mer än ett block catchför att hantera olika klasser av fel, eller multi-catch för att hantera flera fel. Blocket är valfritt, men om det finns, exekveras det oavsett förekomsten av ett fel och är avsett att frigöra de resurser som finallytilldelats under driften av blocket .try
Sedan Java 7 har gränssnittet AutoCloseable[dok. 13] , som låter dig implementera klasser som automatiskt släpper resurser. Objekt av sådana klasser måste skapas inom parentes före try. Ett enkelt exempel på automatisk resursallokering är att läsa innehållet i en fil:
importera java.io.* ; offentlig klass Main { public static void main ( String [] args ) kastar IOException { if ( args . längd < 2 ) { System . fel . println ( "Inget filnamn specificerat." ); återvända ; } Sträng filnamn = args [ 1 ] ; // Den öppnade filen stängs automatiskt av misstag försök ( BufferedReader reader = new BufferedReader ( new FileReader ( filnamn ))) { Stränglinje ; _ for ( int n = 1 ; ( rad = läsare . readLine ()) != null ; ++ n ) { System . ut . println ( n + ": " + rad ); } } catch ( FileNotFoundException e ) { System . fel . println ( "Den angivna filen hittades inte." ); } // till sist { // reader.close(); // automatisk resursstängning // } } }Java följer konceptet med obligatorisk specificering av de felklasser som en metod kan kasta. Detta görs med hjälp av ett nyckelord throwsefter metodbeskrivningen. Om metoden inte specificerar en undantagsklass (eller dess förfader) som kan kastas från metoden, kommer detta att orsaka ett kompileringsfel. Konceptet var tänkt att göra koden självdokumenterande, vilket betecknar vilka undantag en viss metod kan ge, men i praktiken motiverar det sig sällan, eftersom en programmerare på grund av olika omständigheter kan ange en klass som ett undantag som ska kastas Exceptioneller omsluta problematiskt delar av en metod i ett block try... catchför att ignorera enskilda fel, eller - i blocket try... finally, dölja alla möjliga fel. Nackdelen med konceptet är också att programmeraren själv måste definiera och föreskriva de undantag som metoden kan kasta [74] .
Idén med namnutrymmen finns i Java-paket .
Namnet på Java-paketet är latin (gemener och versaler) med siffror (inte det första på raden) och ett understreck (inte det första och inte det sista), som inte är språkinstruktioner (not if, null), separerade med punkter .
Exempel på rätt namn:
Exempel på fel namn:
Paket innehåller klasser, gränssnitt, uppräkningar, anteckningar (etc.) vars namn är latinska (gemener och versaler) med siffror (inte det första på raden). Det kan bara finnas en offentlig klass, gränssnitt (etc.) i en fil. Namnet på den offentliga klassen, gränssnittet (etc.) i filen måste matcha namnet på filen. Varje klass har sin egen namnrymd för funktioner, variabler och underklasser, undergränssnitt (etc.), och du kan få en underklass till en klass med OuterClass.InnerClass, eller så kan du använda OuterClass$InnerClass, så att använda dollarsymbolen i klassnamnet rekommenderas inte.
Programkod "Hej, värld!" .
klass hej värld { public static void main ( String [] args ) { System . ut . println ( "Hej världen!" ); } } Ett exempel på användning av generika importera java.util.List ; importera java.util.ArrayList ; public class Sample { public static void main ( String [] args ) { // Skapa ett objekt från en mall. List < String > strings = new ArrayList <> (); strängar . add ( "Hej" ); strängar . add ( "värld" ); strängar . lägg till ( "!" ); for ( var sträng : strängar ) { System . ut . print ( sträng + " " ); } } } Ett exempel på användning av reflektion importera java.lang.reflect.Field ; importera java.lang.reflect.Method ; class TestClass { privat int värde ; public int getValue () { return value ; } public void setValue ( int valueIn ) { detta . värde = värdeIn ; } } public class Main { public static void main ( String [] args ) { var testClass = new TestClass (); for ( var field : testClass . getClass (). getDeclaredFields ()) { System . ut . printf ( "namn:%s, typ:%s \n" , fält .getName (), fält .getType (). getCanonicalName ( ) ); } for ( var metod : testClass . getClass (). getDeclaredMethods ()) { System . ut . printf ( "namn:%s, returtyp:%s \n" , metod .getName (), metod .getReturnType (). getCanonicalName ( ) ); } } } Anteckningsexempel importera java.lang.annotation.ElementType ; importera java.lang.annotation.Retention ; importera java.lang.annotation.RetentionPolicy ; importera java.lang.annotation.Target ; @Retention ( RetentionPolicy . RUNTIME ) @Target ( ElementType . TYPE ) public @interface MyAnnotation { offentligt booleskt värde () default false ; } @MyAnnotation ( value = true ) public class 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 . ut . printf ( "värde:%s \n" , myAnnotation . värde ()); } } }I sociala nätverk | ||||
---|---|---|---|---|
Tematiska platser | ||||
Ordböcker och uppslagsverk | ||||
|
Java | |
---|---|
Plattformar | |
Sun Technologies | |
Viktiga tredjepartstekniker | |
Berättelse |
|
Språkegenskaper | |
Skriptspråk |
|
Java-konferenser |
|
Programmeringsspråk | |
---|---|
|