Java (programozási nyelv)

A Java általános célú, objektumorientált programozási nyelv, amelyet a Sun Microsystems fejlesztett a ’90-es évek elejétől kezdve egészen 2009-ig, amikor a céget felvásárolta az Oracle.

A Java alkalmazásokat jellemzően bájtkód formátumra alakítják, de közvetlenül natív (gépi) kód is készíthető Java forráskódból. A bájtkód futtatása a Java virtuális géppel történik, ami vagy interpretálja a bájtkódot, vagy natív gépi kódot készít belőle, és azt futtatja az adott operációs rendszeren. Létezik közvetlenül Java bájtkódot futtató hardver is, az úgynevezett Java processzor.

A Java nyelv a szintaxisát főleg a C és a C++ nyelvektől örökölte, viszont sokkal egyszerűbb objektummodellel rendelkezik, mint a C++. A JavaScript szintaxisa és neve hasonló ugyan a Java-hoz, de a két nyelv nem áll olyan szoros rokonságban, mint azt ezekből a hasonlóságokból gondolhatnánk.

Bár a nyelv neve kezdetben Oak (tölgyfa) volt, (James Gosling, a nyelv atyja nevezte így az irodája előtt növő tölgyfáról), később kiderült, hogy ilyen elnevezésű nyelv már létezik, ezért végül Java néven vált ismertté. A Java szó a Oracle védjegye. Ennélfogva engedélye nélkül nem használható mások által kifejlesztett termékek megjelölésére; még például Java-szerű... stb. összetételben sem, mert ez a védjegyjogosult jogaiba ütközik.

Általános tudnivalók 
A Java nyelvet kávézás közben találták ki, innen ered a kávéscsésze ikon.
Négy fontos szempontot tartottak szem előtt, amikor a Javát kifejlesztették:
 objektumorientáltság;
 függetlenség az operációs rendszertől, amelyen fut (többé-kevésbé);
 olyan kódokat és könyvtárakat tartalmazzon, amelyek elősegítik a hálózati programozást;
 távoli gépeken is képes legyen biztonságosan futni.

Objektumorientáltság 
A nyelv első tulajdonsága, az objektumorientáltság („OO”), a programozási stílusra és a nyelv struktúrájára utal. Az OO fontos szempontja, hogy a szoftvert „dolgok” (objektumok) alapján csoportosítja, nem az elvégzett feladatok a fő szempont. Ennek alapja, hogy az előbbi sokkal kevesebbet változik, mint az utóbbi, így az objektumok (az adatokat tartalmazó entitások) jobb alapot biztosítanak egy szoftverrendszer megtervezéséhez. A cél az volt, hogy nagy fejlesztési projekteket könnyebben lehessen kezelni, így csökken az elhibázott projektek száma.

A Java szerepe 
A Java szoftver három igen fontos szerepet tölt be:
 mint programozási nyelv;
 mint köztes réteg (middleware);
 mint platform.

A Java legfontosabb része a Java virtuális gép (Java Virtual Machine – JVM). A JVM mindenütt jelen van (szinte mindenféle berendezés, chip és szoftvercsomag tartalmazza), így a nyelv középszintként és platformként egyaránt működik. Ugyanakkor a nyelv „platformfüggetlen” is, mert a Java virtuális gépek interpretálják a szabványos Java bájtkódot. Ez azt jelenti, hogy egy PC-n megírt Java program minimális módosítás után ugyanúgy fog futni egy javás telefonon is. Innen jön az írd meg egyszer, futtasd bárhol kifejezés. Ez jelentős költségcsökkenést eredményez, mert a kódot csak egyszer kell megírni.

Platformfüggetlenség (hordozhatóság) 
Ez a tulajdonság azt jelenti, hogy a Java nyelven írt programok a legtöbb hardveren (megközelítőleg) ugyanúgy futnak. Ezt úgy érik el, hogy a Java fordítóprogram a forráskódot csak egy úgynevezett Java bájtkódra fordítja le. Ez azután a virtuális gépen fut, ami az illető hardver gépi kódjára fordítja. Léteznek továbbá szabványos könyvtárcsomagok, amelyek – közvetítve a kód és a gép között –, egységes funkcionalitásként teszik elérhetővé az illető hardver sajátosságait (grafika, szálak és hálózat).

Vannak olyan Java fordítóprogramok, amelyek a forráskódot natív gépi kódra fordítják le – ilyen például a GCJ –, ezzel valamelyest felgyorsítva annak futtatását. Cserébe a lefordított program elveszíti hordozhatóságát.

A Sun Microsystems licence ragaszkodik a különböző Java kivitelezések egymással való összeférhetőségéhez (felcserélhetőségéhez?). Egyes cégek, mint például a Microsoft, mégis platformfüggő sajátságokat adtak a nyelvhez, amire a Sun keményen reagált: beperelte a Microsoftot (az amerikai bíróság 20 millió dollár kártérítésre és a sajátos tulajdonságok visszavonására kötelezte a céget).

Válaszként a Microsoft kihagyta a Java rendszert a jövőbeli termékekből és Windows-változatokból. Ez azt jelenti, hogy az Internet Explorer webböngésző alapváltozataiból hiányzik a Java. Így abban az olyan weboldalak, amelyek Java-t használnak, nem fognak helyesen megjelenni. A Windows-felhasználók e problémáját megoldva a Sun és más cégek ingyenesen letölthetővé tették a JVM rendszert azon Windows-változatok számára, amelyekből a virtuális gép hiányzik.

A hordozhatóság megvalósítása technikailag nagyon bonyolult. E közben a Java esetében is sok vita volt. Az „írd meg egyszer, futtasd bárhol” szlogenből „írd meg egyszer, keress hibát mindenhol” lett. 2016-ra a hordozhatóság nem okoz tovább problémát, mivel maga a Java is nyílt szabványokra épül, pl. openGL v. Open POSIX vagy az RFC-k, a Java minden jelentősebb platformon elérhető (Linux, Unix, Windows, más rendszerek pl. AS/400).

Java 2016-ban is sikeres a szerver oldalon a servlet, a JSP és Enterprise JavaBeans, JDBC technológiákkal, integrációs lehetőségeivel, nyelvi eszközeivel, jvm nyelveivel és a nyílt forráskódú közösség tudására is építve.

Biztonságos távoli futtatás 
A Java rendszer volt az első, amely lehetővé tette a távoli gépeken való futtatást sandboxban (homokozóban). Egy kisalkalmazás futtatható a felhasználó gépén (letöltve a Java kódot egy HTTP kiszolgálóról). A kód egy biztonságos környezetben fut, amely nem engedi meg "rossz szándékú" kód futtatását. A gyártók kiadhatnak olyan tanúsítványokat, amelyeket digitálisan aláírnak, ezzel a nevüket adva ahhoz, hogy a kisalkalmazás biztonságos. Így azok a felhasználó felügyelete alatt léphetnek ki a biztonságos környezetből.

A nyelv

A klasszikus „Helló Világ!” Javában 
A következő egyszerű program kiírja azt, hogy „Helló Világ!” az alapértelmezett kimeneti eszközre (ami általában a konzol, de lehet egy fájl vagy bármi más is).
 public class HelloVilag {
     public static void main(String[] args) {
         System.out.println("Helló Világ!");
     }
 }

Vezérlés

Ciklusok

while 
A while egy olyan ciklus, amely a belsejében lévő utasításokat mindaddig ismétlődően végrehajtja, ameddig a megadott feltétel igaz.

 while (logikai kifejezés) {
     utasítás(ok)
 }

do – while 
A do…while ciklus hasonlóan a while ciklushoz, addig hajtja végre a belsejében lévő utasításokat, ameddig a feltétel igaz. A while és a do…while között annyi a különbség, hogy a while az utasítások lefuttatása előtt kiértékeli feltételt, így ha már az első alkalommal a feltétel hamis, a belsejében lévő utasítások egyszer sem futnak le. A do…while ezzel ellentétben viszont csak az utasítások lefuttatása után értékeli ki a kifejezést, tehát ebben az esetben egyszer mindenképpen végrehajtja a belsejében lévő utasításokat.

 do {
     utasítás(ok)
 } while (logikai kifejezés);

for 
A for ciklus általános alakja a következő:

 for (inicializáló kifejezés(ek) ; ciklusfeltétel(ek) ; léptető kifejezés(ek) ) {
     utasítás(ok)
 }

for – each 
A Java 1.5 verziótól kezdve for ciklussal iterálhatóak a tömbök és a java.lang.Iteratable interface implementációi a következő szintaxissal:
 for (elem : tömb) {
     utasítás(ok)
 }
Például:
 for (String s : new String[]{"1","2","3"}) {
     System.out.println(s);
 }

Feltételes utasítások 
 if (logikai kifejezés) {
     utasítás(ok)
 }
 if (logikai kifejezés) {
     utasítás(ok)
 } else {
     utasítás(ok)
 }
Elegendő else if utasításokkal bármilyen komplex ha-akkor szerkezetet ki lehet építeni.
 if (logikai kifejezés) {
     utasítás(ok)
 } else if (logikai kifejezés) {
     utasítás(ok)
 } else if (logikai kifejezés) {
     utasítás(ok)
 } else {
     utasítás(ok)
 }
Az előbbi szerkezet kiváltható, ha ugyanazt az egész, felsorolható ill. string típusú (Java 1.7 óta) kifejezést kell kiértékelni több esetben is. Így kevesebb karakter felhasználásával (rövidebb a kód), átláthatóbb megvalósítást kapunk.
 switch (egész kifejezés) {
     case konstans egész kifejezés:
          utasítás(ok)
          break;
     …
     default:
          utasítás(ok)
          break;
 }

Kivételkezelés 
 try {
     utasítás(ok)
 } catch (kivételtípus) {
     utasítás(ok)
 } catch (kivételtípus) {
     utasítás(ok)
 } finally {
     utasítás(ok)
 }

A Java nyelvben a kivételtípusok osztályok, és közöttük is fennáll típushierarchia. Éppen ezért, ha több catch-ágat használunk egy blokkban, akkor mindig a speciálisabb típust kell korábban feltüntetni, mert a catch ágak kiértékelése fentről lefelé halad.

Egy try után kötelező legalább egy catch vagy egy finally ágat tenni. A catch ágakból több is lehet, de egy try blokk végén csak egy finally lehet.

A könnyebb try-catch blokkot, úgy lehet, hogy a "|" (Alt Gr + W billentyű) megnyomva teszünk két kivételt egy helyre.try {
    utasítás(ok)
} catch (kivételtípus | kivételtípus) {
    utasítás(ok)
}

Feltétel nélküli ugróutasítások 
A Java nem támogatja a goto utasítást, mivel ennek használata spagettikódot eredményezhet. Nagyon ritkán mégis szükség van a goto-ra, a Java lehetővé tesz alternatív megoldásokat, ami a címkézhető continue és break utasítás. A goto fenntartott szó és nem használható azonosítóként.

Korai kilépés a ciklusokból 
A Java nyelv két utasítást is ad a ciklusból való kilépéshez. A
 continue;
utasítás megszakítja a folyamatban levő ismételgetést és egy újabbat kezd (ugyanúgy viselkedik, mint a ciklus elejére ugró goto).

Hasonlóan, a
 break;
utasítás teljesen kilép a ciklusból, és több ismételgetést nem hajt végre. A hatás ugyanaz, mint egy goto utasítás a cikluson kívülre.

A Java break és continue utasításai sokkal hatásosabbak, mint a C és C++ hasonló nevű utasításai, mert képesek egy többszintű ciklusból is kilépni (csak annyi a teendő, hogy megcímkézzük a ciklust és hozzátoldjuk a break vagy continue utasításokhoz. Ugyanezt csak goto utasítással lehet elérni C-ben és C++-ban).

Példa:
  kulso: while (true) {
     belso: while (true) {
         break;             // kilépés a legbelső ciklusból
         break belso;       // ugyancsak kilépés a legbelső ciklusból
         break kulso;       // kilépés a legkülső ciklusból
     }
 }

Korai kilépés az eljárásokból 
A
 return;
utasítás befejez egy eljárást.

A
 return aErtek;
visszaad a hívó eljárásnak egy értéket (aErtek) is visszatéréskor.

Alapvető adattípusok 
A nyelv egyszerű adattípusai, más szóval primitív típusai a következők:

A tömb és a karakterlánc nem egyszerű típusok, hanem objektumok.
A long és float változók inicializálásánál külön meg kell adni, hogy a begépelt szám melyik típusba tartozik: az egész szám literál végére L vagy f betűt írunk. A forráskódba begépelt, ilyen megjelölés nélküli egész számokat integer-ként, a lebegőpontos számokat pedig double-ként kezeli.

Karakterek 
A Java a 16 bites Unicode kódolást (az UTF-16-ot) használja. Ez tartalmazza a szabványos ASCII-karaktereket, de ugyanakkor tartalmazza más nyelvek karakterkészletét is (pl: görög, cirill, kínai, arab stb.). A Java programok mindezeket a karakterkészleteket képesek használni, habár a legtöbb szerkesztőprogram csak a hagyományos ASCII karakterkészletet támogatja.

Interfészek és osztályok 
A Java egyik fontos tulajdonsága, hogy lehetővé teszi interfészek létrehozását, amiket az osztályok megvalósíthatnak. Példa egy interfészre:
 public interface Torolheto {
    public void torol();
 }
Ez az interfész csak annyit határoz meg, hogy minden, ami törölhető, biztosan rendelkezik torol() eljárással. Ennek a fogalomnak több haszna is van, mint például:
 public class Fred implements Torolheto {
     @Override
     public void torol() {
         //Itt kötelező megvalósítani a torol() eljárást
     }
 }
Más osztályban lehetséges a következő:
 public void torolMindent(Torolheto[] lista) {
      for (int i = 0; i < lista.length; i++)
           lista[i].torol();
 }

Léteznek továbbá jelölő interfészek, amelyeknek az implementálása nem jár metódus megvalósításával, csak egy bizonyos tulajdonsággal ruházzák fel az őket implementáló osztályt. Ilyen pl. a Serializable interfész. Az interfészek között is fennállhat öröklődési reláció. Ilyenkor ugyanúgy minden átöröklődik, ahogyan az osztályok esetében.

Egy absztraktként megjelölt osztálynak lehet nem megvalósított (csak deklarált, de nem implementált) metódusa. Példa:

 // Kötelező kulcsszó az abstract, ekkor az osztálynak lehet absztrakt metódusa, de nem lehet példánya
 public abstract class Elvont {
     private int adat;
     public Elvont(int adat) {
         this.adat = adat;
     }
     public int getAdat() {
         return adat;
     }
     // Kötelező kulcsszó az abstract, ekkor nem szabad implementálni a metódust
     public abstract void manipulal();
 }

Ennek értelmében az interfész egy olyan osztály, amely teljesen absztrakt, mert nem lehet megvalósított metódusa, ez alól kivételt képeznek a Java 8-ban bevezetett defult metódusok. Egy absztrakt osztálynak illetve egy interfésznek nem létezhetnek példányai, mert akkor futásidőben nem lenne adott a konkrét viselkedése (a hívott metódus törzse). Egy kivétel azonban mégis létezik, a névtelen osztály. Ez az absztrakt osztály (típus) egyszeri példányosítása, az absztrakt részének a példányosítás helyén történő kötelező megvalósításával. Példa:

 ...
 Torolheto obj = new Torolheto() {
     @Override
     public void torol() {
         //Itt kötelező megvalósítani a torol() eljárást
     }
 };
 ...
 obj.torol(); // Ez itt így már érvényes
 ...

Ha egy osztály implementál egy vagy több interfészt, akkor az az(ok) által előírt (deklarált) minden metódust kötelezően meg kell valósítania (implementálnia kell), kivéve, ha az illető osztály absztrakt. Ekkor a megörökölt, de nem implementált metódusok az osztály meg nem valósított részét képezik. Példa:

 public abstract class TorolhetoElvont extends Elvont implements Torolheto {
     // A következő kikommentezett rész mind megöröklődik
     /*
     private int adat;
     public Elvont(int adat) {
         this.adat = adat;
     }
     public int getAdat() {
         return adat;
     }
     // Kötelező kulcsszó az abstract, ekkor nem szabad implementálni a metódust
     public abstract void manipulal();
     public abstract void torol();
     */

     // Célszerű létrehozni konstruktort, amely lehetővé teszi a megörökölt adat inicializálását
     public TorolhetoElvont(int adat) {
         super(adat);
     }
 }

Lehetséges az öröklési lánc megszakítása; azaz egy osztály mondhatja magáról, hogy végleges. Ekkor belőle nem lehet örököltetni. Példa:

 public final class Vegleges {
    ...
 }

Ki- és bemenet 
A következő kódrészlet bemutatja egy karakter beolvasását a felhasználótól, majd ennek kiíratását:
 public static void main(String[] args) throws java.io.IOException {
    char a;
    System.out.println("Üdvözlöm! Kérem írjon be egy betűt.");
    a = (char) System.in.read();
    System.out.println("A beütött betű: " + a);
 }

Objektumorientált programozás megvalósítása 
A származtatott osztály megadása extends segítségével:
 public class Alaposztaly {
    protected int i;
    public void eljaras(){
       i++;
    }
 }

 public class Szarmaztatott extends Alaposztaly {
    //eljaras felulirasa
    @Override
    public void eljaras() {
        i+=2;
    }
 }

A származtatáskor az alaposztály minden elemét átvette a származtatott osztály, de az eljaras() metódusát felüldefiniáltuk.

Alaposztály konstruktor meghívása a super segítségével
 public class Szarmaztatott extends Alaposztaly {
    private int masikValtozo;
    //Konstruktor
    public Szarmaztatott(int i){
        //Alaposztaly konstruktoranak atadjuk a parametert
        super(i);
        masikValtozo = i;
    }
 }

Származtatáskor kizárólag egyetlen ősosztályt adhatunk meg, viszont tetszőleges számú interfészt implementálhatunk. Így elkerülhető egyrészt a leszármazási láncban a kör (egy osztály tranzitívan önmagától származzon), illetve a megvalósított részek ütközése. C++-ban egy osztálynak több közvetlen őse is lehet, de ekkor egyértelműen jelölni kell, hogy melyik közvetlen ős melyik megvalósított részét használjuk fel, viszont a kör ott sem lehetséges.

Láthatósági körök 

A Java nyelv négyféle láthatóságot támogat a típusok, adattagok és tagfüggvények körében. A felsorolás a legszigorúbbtól halad a legmegengedőbb felé:

 private – privát, azaz csak a definiáló osztály belsejében látható;
 nincs kulcsszó – (angolul default vagy package-private) félnyilvános, azaz a definiáló csomag belsejében látható;
 protected – védett, azaz a definiáló osztály leszármazottaiból látható;
 public – nyilvános, azaz mindenhol látható.

Generikus osztályok 
A java 5-től kezdve megjelent az osztályok paraméterezhetővé tétele. A szintaxis hasonlít a C++ nyelv Standard Template Library (STL)-hez.
List<Integer> list = new ArrayList<Integer>();
A java 7-től megjelent a diamond operátor, amely egyszerűsíti a szintaxist. Az értékadás jobb oldalán nem kell újból megismételni az osztály paraméterezést.
Map<String,Integer> map = new HashMap<>();
Létezik továbbá generikus osztály paraméterezés is Javaban. Erre a következőben mutatunk példákat:
List<?> l1; // bármilyen osztály lista típus, de azonos osztályok listája
List<? super Number> l2; // lehet: List<Number> vagy List<Object>. 
List<? extends Number> l3;//elemei lehetnek Number-ek vagy bármilyen Number bármilyen kiterjesztése

Lambda kalkulus megvalósítása 
A Java 8-cal bekerült a Java nyelvi elemei közé a Lambda kalkulus, amit funkcionális nyelvekből vettek át.

Java class fájl verziók
Minden lefordított class fájl a következő bájt sorozattal kezdődik: CAFEBABE, a 7-8. bájt pedig a class fájl verzióját adja meg. A következő táblázat az adott java verziókhoz tartozó class fájlok verzióit foglaljuk össze:
 Java 1.1 fő verzió szám: 45
 Java 1.2 fő verzió szám: 46
 Java 1.3 fő verzió szám: 47
 Java 1.4 fő verzió szám: 48
 Java 5 fő verzió szám: 49
 Java 6 fő verzió szám: 50
 Java 7 fő verzió szám: 51
 Java 8 fő verzió szám: 52
 Java 9 fő verzió szám: 53
 Java 10 fő verzió szám: 54
 Java 11 fő verzió szám: 55
 ...
 Java 19 fő verzió szám: 63

A Java története 

A Java nyelv története összeforrt a Sun Microsystems Java fordítójával és virtuális gépével és az ezekhez kapcsolódó fejlesztői programcsomaggal (Java SDK vagy újabban JDK – Java Development Kit), amely a Java nyelv és ahhoz kapcsolódó szabványok standard implementációjának tekinthető. A nyílt szabványt képviselő, de zárt forráskódú Java eszközök miatt sok kritikát kapott a Sun a Free Software Foundationtól. Valószínűleg ennek is köszönhető, hogy a Sun Microsystems 2007-ben a Java SE (Standard Edition), Java ME (Micro Edition) és a Java EE (Enterprise Edition) GPL licenc alatt nyílt forráskódúvá, azaz szabad szoftverré teszi, ahogy ez már részben meg is történt a Java EE esetében, nem GPL-kompatibilis licenccel.

Java FX 
2006-ban megjelent egy változata a Java-nak JavaFX néven, ami egy szkriptnyelvet takar. Gyorsan egyszerűen tudunk vele asztali alkalmazásokat készíteni.

A JavaFX drasztikusan lerövidült termelési ciklust kínál a Java-fejlesztők és a webfejlesztők számára egyaránt, valamint megkönnyíti a grafikát, videót, audiót, animációt és gazdag szövegfunkciókat tartalmazó alkalmazások létrehozását. A JavaFX abból a szempontból egyedülálló, hogy egységesített fejlesztési és telepítési modellt kínál kifejezésteli, gazdag internetes alkalmazások (RIA) asztali számítógépen, böngészőn és mobilon történő kiépítéséhez. Ráadásul az új JavaFX mobil emulátor használata mellett a fejlesztők előzetesen megtekinthetik alkalmazásaikat a közeljövőben bevezetett JavaFX mobilplatformon, amely 2009 tavaszától lesz elérhető a Sun mobilpartnerei számára.

Java Development Kit 

A Java Development Kit (JDK) egy Oracle termék Java fejlesztők számára, amely tartalmazza a Java fordítót (javac), egy teljes értékű Java Runtime Environment (JRE)-t, azaz Java futtató környezetet, és egyéb más fejlesztő eszközöket.

A JDK nyílt letöltése megszűnt 2019. április 16-án új licenc bevezetése miatt. 
Innentől kezdve egy Oracle fiók létezése szükséges a letöltéshez. Az Oracle az eddig openJDK-t tette meg java fő ágának és az Oracle JDK ennek egy leágazás, ami a nem nyílt kódú eszközöket is tartalmazza. Ezek köre fokozatosan csökken, az Oracle mind több java-s eszközének forráskódját tette át az openJdk kód bázisba.

Az OpenJDK, azaz a Java nyílt változatát, továbbra is lehet személyes adatok megadása nélkül használni, bármilyen célra.

A Java 19-től az Oracle Jdk-t megint le lehet tölteni szabadon és fel lehet használni ingyenesen bármilyen célra. 2023-től az Oracle Jdk subscription díjai megint változnak.

JDK verziók 

 1.0 (1996) – kódneve Oak (tölgy), ez volt az első verziója a Java virtuális gépnek és az osztálykönyvtáraknak. Ez a következő főbb eszközöket jelentette: jvm a java programok futtatásához, java plugin böngészőhöz, java fordító, debugger, applet viewer. Főbb könyvtárak léteztek már a grafikus megjelenítéshez (AWT), audio-hoz, animációhoz, és a hálózat kezeléshez. Nyelvi szinten a nyelvet jellemezték a következők: Objektum Orientáltság, C/C++-hoz hasonló szintaxis, 1 fájl 1 osztály elve, interface-ek, absztrakt osztályok. Továbbá jellemző volt még az interpretált végrehajtás is.
 1.1 (1997) – itt jelent meg először a belső osztály fogalom – ami lehetővé teszi több osztály egymásba ágyazását –, valamint a JDBC az adatbázis kezeléshez, RMI a távoli metódus hívásokhoz, a Reflection API az osztály/példány elemzéshez, dinamikus példányosításhoz/metódus híváshoz.
 1.2 (1998) – kódneve Playground (játszótér), ez a verzió számottevő mérföldkő volt a nyelv evolúciójában. Azért, hogy ezt kihangsúlyozza, a Sun hivatalosan Java 2-nek nevezte el. Nyelvi szintű változások: megjelent a strictfp kulcsszó. API szintű változások: része lett a Swing grafikus API, a JVM-be belekerült a JIT-compiler, Java plugin, Java IDL-egy IDL fordító a CORBA alkalmazásokhoz, Collection framework.
 1.3 (2000) – kódneve Kestrel, csak néhány kisebb változtatást végeztek el rajta: ekkor került be a Hotspot JVM a rendszerbe, a Java Sound, a JNDI API is hivatalos része lett a belső rendszernek.Hozzáadtak egy új JPDA API-t a debuggoláshoz és a szintetikus proxy osztályokat.
 1.4 (2002) – kódneve Merlin. Nyelvi bővítés: assert kulcsszó a teszteléshez (ala JUnit). API változások: új API a reguláris kifejezések kezelésére (RegExp a Perl-ből), kivétel láncolás, NIO, Java logging API, Image IO, JAXP- XSLT és XML feldolgozáshoz, JCE, JSSE, JAAS – java biztonság, részévé vált a Java Web Start a vastag kliensek könnyebb webes futtatásához, update-eléséhez, Preferences API.
 5 (2004) – belső számozás szerint 1.5, kódneve Tiger, újdonságai nyelvi szinten a generic-ek, a megszámlálható elemet tartalmazó tömbön való automatikus végighaladó ciklus, az adattípusok automatikus objektummá alakítása (autoboxing), típusbiztos enum, metódus argumetruma lehet változó számú (varargs C-szerűen), static import, metaadatok kezelése forrásfájlban (annotation), System.out.printf C-ből áthozása. Továbbá számos API bővítés, hozzáadás, és JVM változás is volt.
 6 (2006) – belső számozás szerint 1.6.0, kódneve Mustang. Decemberben jelent meg a végleges változat kiterjesztett nyomkövetési és felügyeleti megoldásokkal, Java Scripting API: szkriptnyelvek támogatása (JVM-en belül ill. azon kívül), grafikusfelület-tervezést támogató kiegészítésekkel, Java Compiler API megjelenése, JDBC 4.0 – Apache Derby előrecsomagolva a JDK-ba, pluggable annotációk, Swing GUI elemek bővítése pl. rendezhető / szűrhető táblázatok, szinkronizáció és fordítás optimalizálása, Swing felület jelentős gyorsítása / optimalizálása, JAXWS,JAXB.
 7 (2011) – kódneve Dolphin. 2011. július 28-ától érhető el hivatalosan. Főbb újdonságai a teljesség igénye nélkül: JVM támogatás a dinamikus nyelvekhez, nyelvi bővítések: Diamond operátor, String-ek engedélyezése switch utasításban,több kivétel kezelése egyszerre, automatikus erőforrás kezelés,egész számokban '_' használata a könnyebb tagolásért, új NIO2 könyvtár, GPU-t kihasználni képes XRender API a Java 2D-hez, Fork és Join keretrendszer a könnyebb párhuzamosság használatához.
 8 (LTS)(2014 április): Lambda kalkulus beépítése nyelvi szinten a Lambda projekt keretében, valamint a 7-be még nem beépített Coin projekt részek. Nashorn projekt egy Javascript motor beépítése, Date and Time API (Jodatime szerű megoldás), permanent generation eltávolítása.
Gyors verziókiadás (félévente):
 9 (2017 szeptember): JDK modularizáció, amit a Jigsaw projekt keretében dolgoztak ki, Money and Currency API, nagyobb integráció a Java FX-szel, automatikus párhuzamosítás az OpenCL-lel.
 10: Erről egyelőre viszonylag kevés tudható, várható pl. a primitív típusok teljes eltávolítása, és a 64 biten címezhető tömbök bevezetése, a nagy adathalmazok támogatásához.
 11 (LTS): A var típus bevezetése
 12: Új switch utasítás, Shenandoah GC bevezetése nagyon rövid GC felfüggesztési időkkel (10-500 ms),Microbenchmark suite hozzáadása,JVM constants API hozzáadása, AArch64 esetén 1 port használat a korábbi kettő helyett, G1 kiugrás kevert gyűjtések esetén, nem használt memória azonnali visszaadása G1 esetén
 13 (2019 szeptember 17): dinamikus Class Data Sharing (CDS) archív listával,ZGC azonnal nem használt memória visszaadása, legacy Socket API újraírása, új switch utasítás bővítése yield-del, új szöveg blokkok bevezetése, ahol nem kell escape-elni, as-is használat
 17 (LTS)

A 17-es verziótól az Oracle gyorsítja az LTS-esek piacra kerülését. Az eredeti tervek szerinti 3 éves ciklus 2 évesre módosul. A következő LTS a 21-es lesz, ami 2023-ben fog érkezni.

Kapcsolódó szabad szoftverek 
 GCJ – Nyílt forrású Java fordítóprogram, amely a GNU Compiler Collection része, képes Java bájtkódot vagy natív gépi kódot generálni számos géptípusra
 A Jakarta projekt szabad Java szoftvert készít, főleg webes programok írásához szükséges eszközöket
 Eclipse – ingyenes integrált fejlesztői környezet
 NetBeans – ingyenes integrált fejlesztői környezet
 IntelliJ IDEA – integrált fejlesztői környezet kereskedelmi és ingyenes változattal
 JUnit – egységteszt segédeszköz

Jegyzetek

További információk 
 A Java hivatalos webhelye
Az OpenJDK hivatalos weboldala
 Sun oktatói weboldalak
 Java Standard Edition 16 dokumentációja
 Szabad szoftverek Java nyelven 
 Javafórum wiki

Programozási nyelvek
Java