Java- ja C++-ohjelmointikielten vertailu

Wikipediasta
Siirry navigaatioon Siirry hakuun

Java ja C++ ovat kaksi merkittävää olio-ohjelmointikieltä. Monien kielten suosion mittareiden mukaan nämä kaksi kieltä ovat dominoineet olio- ja korkean suorituskyvyn ohjelmistokehitystä suuren osan 2000-luvulta, ja niitä verrataan ja verrataan usein suoraan. Java ilmestyi noin 10 vuotta myöhemmin ja sen syntaksi perustui C/C++:aan.

Suunnittelun tavoitteet

[muokkaa | muokkaa wikitekstiä]

Ohjelmointikielten C++ ja Java erot voidaan jäljittää niiden perintöön, sillä niillä on erilaiset suunnittelutavoitteet.

C++ on suunniteltu järjestelmien ja sovellusten ohjelmointiin (eli infrastruktuuriohjelmointiin) laajentaen proseduuriohjelmointikieltä C, joka oli suunniteltu tehokkaaseen suorittamiseen. C++ lisäsi tuen oliopohjaiselle ohjelmointille, poikkeusten käsittelylle, elinikäiseen resurssien hallintaan (RAII), yleiseen ohjelmointiin, mallin metaohjelmointiin ja C++ Standard Libraryyn, joka sisältää yleisiä säilöjä ja algoritmeja (Standard Template Library tai STL), ja monia muita yleiskäyttöisiä tiloja.

Java on yleiskäyttöinen, samanaikainen, luokkapohjainen, olio-ohjelmointikieli, joka on suunniteltu minimoimaan toteutusriippuvuudet. Se luottaa siihen, että Java-virtuaalikone on turvallinen ja erittäin kannettava. Se on niputettu laajan kirjaston kanssa, joka on suunniteltu tarjoamaan täydellinen abstraktio taustalla olevasta alustasta. Java on staattisesti kirjoitettu oliokieli, joka käyttää samanlaista syntaksia kuin C++ (mutta ei yhteensopiva sen kanssa). Se sisältää dokumentaatiojärjestelmän nimeltä Javadoc.

Erilaiset tavoitteet C++ ja Javan kehittämisessä johtivat erilaisiin periaatetteisiin ja suunnittelun kompromisseihin kielten välillä. Erot ovat seuraavat:

C++ Java
Laajentaa C-ohjelmointikieltä olio-ohjelmoinnilla ja geneerisellä ohjelmoinnilla. C-koodia voidaan käyttää asianmukaisesti. Vahvasti ottanut vaikutteita C++/C syntaksista.
Yhteensopivaa C-ohjelmointikielen kanssa, joitakin rajatapauksia lukuun ottamatta. Tarjoaa Java Native Interface ja äskettäin Java Native Access joiden avulla voidaan kutsua suoraan C/C++ koodia.
Kirjoita kerran, käännä missä tahansa (WOCA). Kirjoita kerran, suorita missä tahansa/kaikkialla (WORA/WORE).
Sallii proseduraalisen ohjelmoinnin, funktionaalisen ohjelmoinnin, olio-ohjelmoinnin, geneerisen ohjelmoinnin, ja TMP-ohjelmoinnin. Suosii malleja. Sallii proseduraalisen ohjelmoinnin, Funktionaalisen ohjelmoinnin (Java 8 lähtien) ja generisen ohjelmoinnin (Java 5 lähtien), mutta vahvasti kehottaa käyttämään olio-ohjelmoinnin malleja. Sisältää tuen skriptauskielten luomiselle.
Pyörii natiivisti suoritettavana konekielenä kohteen käskysarjoja noudattaen. Pyörii Java virtuaalikoneessa (JVM).
Tarjoaa oliotyyppejä ja tyyppinimiä. Sallii heijastuksen RTTI kautta. On heijastettava, sallien metaohjelmoinnin and dynaamisen koodin generoinnin ajonaikana.
On useita binääriyhteensopivuusstandardeja (yleisin Microsoft (MSVC kääntäjä) ja Itanium/GNU (melkein kaikille muille kääntäjille)). On yksi binääriyhteensopivuusstandardeja, järjestelmäriippumaton käyttöjärjestelmälle ja kääntäjälle.
Natiivi etumerkitön laskuoppi tuettu. Natiivi etumerkitön laskuoppi ei tuettu. Java 8 muuttaa osan tästä, mutta näkökulma on epäselvä.[1]
Standardisoidut minimirajat kaikille numeerisille tyypeille, mutta oikeat koot ovat määriteltävissä itse. Standardisoidut tyypit ovat saatavilla standardi kirjaston kautta. <cstdint>. Standardisoidut rajat ja koot kaikille primitiivisille tyypeille kaikilla alustoilla.

Kielen ominaisuudet

[muokkaa | muokkaa wikitekstiä]
  • Javassa on kontekstivapaa kielioppi, jonka jäsentäminen voidaan suorittaa yksinkertaisella LALR-parserilla. C++ jäsentäminen on monimutkaisempaa, esimerkiksi, Foo<1>(3); on sarja vertailuja, jos Foo on muuttuja, mutta se luo olion, jos Foo on luokkamallin nimi.
  • C++ mahdollistaa nimiavaruus-tason vakiot, muuttujat ja funktiot. Vastaavasti Javassa vastaavien olioiden on kuuluttava johonkin tiettyyn tyyppiin ja ne on määriteltävä tyypin määrityksen sisällä, joko luokassa tai rajapinnassa.
  • C++:ssa oliot ovat arvoja, kun taas Javassa ne eivät ole. C++ käyttää arvo semantiikkaa oletuksena, kun taas Java käyttää viittaussemantiikkaa. Osoitinta tai viittausta voidaan käyttää viittaussemantiikan valitsemiseen C++:ssa.
C++ Java
class Foo {          // Luokan julistus
    int x = 0;       //  Yksityinen jäsenmuuttuja. Alustetaan
                     //  0:ksi.
    public:
      Foo() : x(0)     //  Luokan Foo rakentaja; alustaa
      {}               //  x:n nollaksi. Mikäli alustaja jätetään pois,
                     //  muuttuja alustettaisiin arvoon, joka 
                     //  on annettu x:n julistuksessa.

      int bar(int i) { // Jäsenfunktio bar()
          return 3*i + x;
      }
};
class Foo {               // Määrittää luokan Foo
    private int x;        // Jäsenmuuttuja, yleensä julistetaan
                          // yksityiseksi kapsuloinnin pakottamiseksi
                          // alustetaan arvoon 0 oletuksena

    public Foo() {        // Foo:n rakentaja
    }                     // argumentiton rakentaja luodaan oletuksena
    public int bar(int i) {        // Jäsenmetodi bar()
        return 3*i + x;
    }
}
Foo a;
// julistaa Foo-olion arvon,
// alustetaan käyttäen oletusrakentajaa

// Toista rakentajaa voidaan kutsua seuraavasti
Foo a(args);
// tai (C++11):
Foo a{args};
Foo a = new Foo();
// Julistaa viittauksen uuteen Foo-olioon
// alustus tapahtuu oletusrakentajaa käyttämällä

// Toista rakentajaa voidaan käyttää seuraavasti
Foo a = new Foo(args);
Foo b = a;
// Kopioi a:n sisällön uuteen Foo-olioon b
// Vaihtoethoinen syntaksi on "Foo b(a)"
// Foo b = a;
// julistaisi b:n a:n osoittaman olion viittaukseksi
Foo b = a.clone();
// kopioi a:n osoittaman olion sisällön uuteen Foo-olioon
// asettaa viittauksen b osoittamaan tähän olioon
// Foo luokan tulee implementoida "Cloneable" rajapintaa, jotta koodi kääntyy
a.x = 5; // Muokkaa oliota a
a.x = 5; // Muokkaa a:n viittaamaa oliota
std::cout << b.x << std::endl;
// Tulostaa 0, sillä b on eri olio kuin a
System.out.println(b.x);
// Tulostaa 0, sillä b on eri olio kuin a
Foo *c;
// Julistaa c:n a:n osoittimeksi
// Foo olio (alustettu määrittelemättömäksi, voi osoittaa minne tahansa)
Foo c;
// Julistaa c:n Foo-olion viittaukseksi
// (alustettu null-arvoon, jos c on luokan jäsen; on tarpeen alustaa c ennen käyttöä jos se on paikallinen muuttuja)
c = new Foo;
// c on asetettu new-operaattorin luomaan Foo-olion osoitteeseen
c = new Foo();
// kiinnittä c:n viittaamaan uutta Foo-oliota
Foo &d = *c;
// kiinnittää d:n osoittaamaan samaan objektiin mihin c osoittaa
Foo d = c;
// kiinnittää d:n viittaamaan samaan olioon kuin c
c->x = 5;
// muokkaa c:n osoittmaa oliota
c.x = 5;
// muokkaa c:n viittaamaa oliota
d.bar(5);  // kutsuu Foo::bar() metodia kohteeelle a
c->bar(5); // kutsuu Foo::bar() metodia kohteelle *c
d.bar(5); // kutsuu Foo.bar() metodia kohteelle a
c.bar(5); // kutsuu Foo.bar() metodia kohteelle c
std::cout << d.x << std::endl;
// Tulostaa arvon 5, koska d viittaa samaan objektiin, mihin c osoittaa
System.out.println(d.x);
// Tulostaa arvon 5, koska d viittaa samaan objektiin kuin c


  1. Unsigned Integer Arithmetic API now in JDK 8 blogs.oracle.com. Arkistoitu 25 February 2017. Viitattu 17 March 2014.