Java

Η Java είναι  αντικειμενοστρεφής γλώσσα προγραμματισμού που σχεδιάστηκε από την εταιρεία πληροφορικής Sun Microsystems. 

 Ιστορία 
Στις αρχές του 1991, η Sun αναζητούσε το κατάλληλο εργαλείο για να αποτελέσει την πλατφόρμα ανάπτυξης λογισμικού σε μικρο-συσκευές (έξυπνες οικιακές συσκευές έως πολύπλοκα συστήματα παραγωγής γραφικών). Τα εργαλεία της εποχής ήταν γλώσσες όπως η C++ και η C. Μετά από διάφορους πειραματισμούς προέκυψε το συμπέρασμα ότι οι υπάρχουσες γλώσσες δεν μπορούσαν να καλύψουν τις ανάγκες τους. Ο "πατέρας" της Java, James Gosling, που εργαζόταν εκείνη την εποχή για την Sun, έκανε ήδη πειραματισμούς πάνω στη C++ και είχε παρουσιάσει κατά καιρούς κάποιες πειραματικές γλώσσες (C++ ++, που μετέπειτα ονομάστηκε C# ) ως πρότυπα για το νέο εργαλείο που αναζητούσαν στην Sun. Τελικά μετά από λίγο καιρό κατέληξαν με μια πρόταση για το επιτελείο της εταιρίας, η οποία ήταν η γλώσσα Oak. Το όνομά της το πήρε από το ομώνυμο δένδρο (βελανιδιά) το οποίο ο Gosling είχε έξω από το γραφείο του και έβλεπε κάθε μέρα.

 Από την Oak στη Java 
Η Oak ήταν μία γλώσσα που διατηρούσε μεγάλη συγγένεια με την C++. Παρόλα αυτά είχε πολύ πιο έντονο αντικειμενοστρεφή (object oriented) χαρακτήρα σε σχέση με την C++ και χαρακτηριζόταν για την απλότητα της. Σύντομα η υπεύθυνοι ανάπτυξης της νέας γλώσσας ανακάλυψαν ότι το όνομα Oak ήταν ήδη κατοχυρωμένο οπότε κατά την διάρκεια μιας εκ των πολλών συναντήσεων σε κάποιο τοπικό καφέ αποφάσισαν να μετονομάσουν το νέο τους δημιούργημα σε Java που εκτός των άλλων ήταν το όνομα της αγαπημένης ποικιλίας καφέ για τους δημιουργούς της. Η επίσημη εμφάνιση της Java αλλά και του HotJava (πλοηγός με υποστήριξη Java) στη βιομηχανία της πληροφορικής έγινε το Μάρτιο του 1995 όταν η Sun την ανακοίνωσε στο συνέδριο Sun World 1995. Ο πρώτος μεταγλωττιστής (compiler) της ήταν γραμμένος στη γλώσσα C από τον James Gosling. Το 1994, ο A.Van Hoff ξαναγράφει τον μεταγλωττιστή της γλώσσας σε Java, ενώ το Δεκέμβριο του 1995 πρώτες οι IBM, Borland, Mitsubishi Electronics, Sybase και Symantec ανακοινώνουν σχέδια να χρησιμοοιήσουν τη Java για την δημιουργία λογισμικού. Από εκεί και πέρα η Java ακολουθεί μία ανοδική πορεία και είναι πλέον μία από τις πιο δημοφιλείς γλώσσες στον χώρο της πληροφορικής. Στις 13 Νοεμβρίου του 2006 η Java έγινε πλέον μια γλώσσα ανοιχτού κώδικα (GPL) όσον αφορά το μεταγλωττιστή (javac) και το πακέτο ανάπτυξης (JDK, Java Development Kit).

 Η εξαγορά από την Oracle και το μέλλον της Java 
Στις 27 Απριλίου 2010 η εταιρία λογισμικού Oracle Corporation ανακοίνωσε ότι μετά από πολύμηνες συζητήσεις ήρθε σε συμφωνία για την εξαγορά της Sun Microsystems και των τεχνολογιών (πνευματικά δικαιώματα/ πατέντες) που η δεύτερη είχε στην κατοχή της ή δημιουργήσει. Η συγκεκριμένη συμφωνία θεωρείται σημαντική για το μέλλον της Java και του γενικότερου οικοσυστήματος τεχνολογιών γύρω από αυτή μιας και ο έμμεσος έλεγχος της τεχνολογίας και η εξέλιξη της περνάει σε άλλα χέρια.

 Εκδόσεις 
Σήμερα οι υποστηριζόμενες εκδόσεις είναι οι Java 8 και 9. Οι σημαντικότερες που έχουν κυκλοφορήσει, με τις αντίστοιχες ημερομηνίες κυκλοφορίας, είναι οι εξής :
 JDK 1.0 (23 Ιανουαρίου 1996)(Αγγλικά) «JAVASOFT SHIPS JAVA 1.0». Ιστορική ανακοίνωση, που δημοσιεύθηκε στις 23/1/1996.
 JDK 1.1 (19 Φεβρουαρίου 1997)
 J2SE 1.2 (8 Δεκεμβρίου 1998)
 J2SE 1.3 (8 Μαΐου 2000)
 J2SE 1.4 (6 Φεβρουαρίου 2002)
 J2SE 5.0 (30 Σεπτεμβρίου 2004)
 Java SE 6 (11 Δεκεμβρίου 2006)
 Java SE 7 (28 Ιουλίου 2011)
 Java SE 8 (18 Μαρτίου 2014)
 Java SE 9 (21 Σεπτεμβρίου 2017)
Java SE 10 (20 Μαρτίου 2018)
Java SE 11 (LTS*) (25 Σεπτεμβρίου 2018)
Java SE 12 (Μάρτιος 2019)
Java SE 13 (Σεπτέμβριος 2019)
Java SE 14 (Μάρτιος 2020)
Java SE 15 (Σεπτέμβριος 2020)
Java SE 16 (Μάρτιος 2021)
Java SE 17 (LTS*) (Σεπτέμβριος 2021)
LTS = Long-Term Support. Είναι η έκδοση η οποία προορίζεται να παραμείνει στάνταρντ για τα επόμενα χρόνια. 

 Τα χαρακτηριστικά της Java 

Ένα από τα βασικά πλεονεκτήματα της Java έναντι των περισσότερων άλλων γλωσσών είναι η ανεξαρτησία του λειτουργικού συστήματος και πλατφόρμας. Τα προγράμματα που είναι γραμμένα σε Java εκτελούνται ακριβώς το ίδιο σε Windows, Linux, Unix και Macintosh (σύντομα θα τρέχουν και σε Playstation καθώς και σε άλλες κονσόλες παιχνιδιών) χωρίς να χρειαστεί να ξαναγίνει μεταγλώττιση (compiling) ή να αλλάξει ο πηγαίος κώδικας για κάθε διαφορετικό λειτουργικό σύστημα. Για να επιτευχθεί όμως αυτό χρειαζόταν κάποιος τρόπος έτσι ώστε τα προγράμματα γραμμένα σε Java να μπορούν να είναι «κατανοητά» από κάθε υπολογιστή ανεξάρτητα του είδους επεξεργαστή (Intel x86, IBM, Sun SPARC, Motorola) αλλά και λειτουργικού συστήματος (Windows, Unix, Linux, BSD, Mac OS). Ο λόγος είναι ότι κάθε κεντρική μονάδα επεξεργασίας κατανοεί διαφορετικό κώδικα μηχανής. Ο συμβολικός κώδικας (assembly) που μεταφράζεται και εκτελείται σε Windows είναι διαφορετικός από αυτόν που μεταφράζεται και εκτελείται σε έναν υπολογιστή Macintosh. Η λύση δόθηκε με την ανάπτυξη της Εικονικής Μηχανής (Virtual Machine ή VM ή ΕΜ στα ελληνικά).

 Η εικονική μηχανή της Java 
Αφού γραφεί κάποιο πρόγραμμα σε Java, στη συνέχεια μεταγλωττίζεται μέσω του μεταγλωττιστή javac, ο οποίος παράγει έναν αριθμό από αρχεία .class (κώδικας byte ή bytecode). Ο κώδικας byte είναι η μορφή που παίρνει ο πηγαίος κώδικας της Java όταν μεταγλωττιστεί. Όταν πρόκειται να εκτελεστεί η εφαρμογή σε ένα μηχάνημα, το Java Virtual Machine που πρέπει να είναι εγκατεστημένο σε αυτό θα αναλάβει να διαβάσει τα αρχεία .class. Στη συνέχεια τα μεταφράζει σε γλώσσα μηχανής που να υποστηρίζεται από το λειτουργικό σύστημα και τον επεξεργαστή, έτσι ώστε να εκτελεστεί. Αυτό συμβαίνει με την παραδοσιακή Εικονική Μηχανή (Virtual Machine).(Αγγλικά) «The Java® Virtual Machine Specification, SE 7 Edition» από docs.oracle.com. Ανακτήθηκε 27/1/2018. Πιο σύγχρονες εφαρμογές της εικονικής Μηχανής μπορούν και μεταγλωττίζουν εκ των προτέρων τμήματα bytecode απευθείας σε κώδικα μηχανής (εγγενή κώδικα ή native code) με αποτέλεσμα να βελτιώνεται η ταχύτητα. Χωρίς αυτό δε θα ήταν δυνατή η εκτέλεση λογισμικού γραμμένου σε Java. Η JVM είναι λογισμικό που εξαρτάται από την πλατφόρμα, δηλαδή για κάθε είδος λειτουργικού συστήματος και αρχιτεκτονικής επεξεργαστή υπάρχει διαφορετική έκδοση του. Έτσι υπάρχουν διαφορετικές JVM για Windows, Linux, Unix, Macintosh, κινητά τηλέφωνα, παιχνιδομηχανές κλπ.

Οτιδήποτε θέλει να κάνει ο προγραμματιστής (ή ο χρήστης) γίνεται μέσω της εικονικής μηχανής. Αυτό βοηθάει στο να υπάρχει μεγαλύτερη ασφάλεια στο σύστημα γιατί η εικονική μηχανή είναι υπεύθυνη για την επικοινωνία χρήστη - υπολογιστή. Ο προγραμματιστής δεν μπορεί να γράψει κώδικα ο οποίος θα έχει καταστροφικά αποτελέσματα για τον υπολογιστή γιατί η εικονική μηχανή θα τον ανιχνεύσει και δε θα επιτρέψει να εκτελεστεί. Από την άλλη μεριά ούτε ο χρήστης μπορεί να κατεβάσει «κακό» κώδικα από το δίκτυο και να τον εκτελέσει. Αυτό είναι ιδιαίτερα χρήσιμο για μεγάλα κατανεμημένα συστήματα όπου πολλοί χρήστες χρησιμοποιούν το ίδιο πρόγραμμα συγχρόνως.

 Ο συλλέκτης απορριμμάτων (Garbage Collector) 

Ακόμα μία ιδέα που βρίσκεται πίσω από τη Java είναι η ύπαρξη του συλλέκτη απορριμμάτων (Garbage Collector). Συλλογή απορριμμάτων είναι μία κοινή ονομασία που χρησιμοποιείται στον τομέα της πληροφορικής για να δηλώσει την ελευθέρωση τμημάτων μνήμης από δεδομένα που δε χρειάζονται και δε χρησιμοποιούνται άλλο. Αυτή η απελευθέρωση μνήμης στη Java είναι αυτόματη και γίνεται μέσω του συλλέκτη απορριμμάτων. Υπεύθυνη για αυτό είναι και πάλι η εικονική μηχανή η οποία μόλις «καταλάβει» ότι ο σωρός (heap) της μνήμης (στη Java η συντριπτική πλειοψηφία των αντικειμένων αποθηκεύονται στο σωρό σε αντίθεση με τη C++ όπου αποθηκεύονται κυρίως στη στοίβα) κοντεύει να γεμίσει ενεργοποιεί το συλλέκτη απορριμμάτων. Έτσι ο προγραμματιστής δε χρειάζεται να ανησυχεί για το πότε και αν θα ελευθερώσει ένα συγκεκριμένο τμήμα της μνήμης, ούτε και για σφάλματα δεικτών. Αυτό είναι ιδιαίτερα σημαντικό γιατί είναι κοινά τα σφάλματα προγραμμάτων που οφείλονται σε λανθασμένο χειρισμό της μνήμης.

Η προεπιλεγμένη μέθοδος για συλλογή απορριμμάτων μοιράζει το σωρό σε δύο κομμάτια. Το πρώτο, χρησιμοποιείται για νέα αντικείμενα και λέγεται μαιευτήριο. Αφού επιβιώσουν ένα προεπιλεγμένο αριθμό εκκαθαρίσεων στο μαιευτήριο, ώριμα αντικείμενα μεταφέρονται στο δεύτερο κομμάτι του σωρού. Το μαιευτήριο είναι μοιρασμένο σε δύο κομμάτια, τον από-χωρο και τον προς-χωρο. Νέα αντικείμενα τοποθετούνται αρχικά στον από-χωρο. Όταν αυτός γεμίσει, ζωντανά αντικείμενα αντιγράφονται στον προς-χωρο και οι δύο χώροι ανταλλάσσουν ρόλο.

 Επιδόσεις 
Παρόλο που η εικονική μηχανή προσφέρει όλα αυτά (και όχι μόνο) τα πλεονεκτήματα, η Java αρχικά ήταν πιο αργή σε σχέση με άλλες προγραμματιστικές γλώσσες υψηλού επιπέδου (high-level) όπως η C++. Εμπειρικές μετρήσεις στο παρελθόν είχαν δείξει ότι η C++ μπορούσε να είναι αρκετές φορές γρηγορότερη από την Java. Ωστόσο γίνονται προσπάθειες από τη Oracle για τη βελτιστοποίηση της εικονικής μηχανής, ενώ υπάρχουν και άλλες υλοποιήσεις της εικονικής μηχανής από διάφορες εταιρίες (όπως της IBM), οι οποίες μπορεί σε κάποια σημεία να προσφέρουν καλύτερα και σε κάποια άλλα χειρότερα αποτελέσματα. Επιπλέον με την καθιέρωση των μεταγλωττιστών JIT (Just In Time), οι οποίοι μετατρέπουν τον κώδικα byte απευθείας σε γλώσσα μηχανής, η διαφορά ταχύτητας από τη C++ έχει μικρύνει κατά πολύ.Horstmann C. 2015, βλ. πηγές σελ. 5-6, 7

Οι τελευταίες εκδόσεις του javac με τη χρήση της τεχνολογίας Hot Spot έχουν καταφέρει αξιόλογες επιδόσεις που πλησιάζουν ή και ξεπερνούν σε μερικές περιπτώσεις τον εγγενή κώδικα.

 Κώδικας 
Ως αντικειμενοστρεφής γλώσσα, η Java βασίζεται σε κλάσεις και αντικείμενα. Μια κλάση (class) είναι μια φόρμα για τη δημιουργία αντικειμένων (objects ή instances). Αφού πρώτα δημιουργηθεί μια κλάση, στη συνέχεια  μπορεί να χρησιμοποιηθεί για την παραγωγή αντικειμένων. Παρομοιάζοντας, θα μπορούσαμε να πούμε ότι η κλάση αποτελεί μια "συνταγή" για τη δημιουργία αντικειμένων. Μια κλάση περιγράφει μια οντότητα, για παράδειγμα η κλάση Student μπορεί να περιγράψει ένα φοιτητή, η κλάση Employee έναν εργαζόμενο, η κλάση Car ένα αυτοκίνητο κ.λπ. Μια κλάση περιλαμβάνει α) πεδία (fields) και β) μεθόδους (methods). Τα πεδία αντιστοιχούν σε ιδιότητες των αντικειμένων της κλάσης ενώ οι μέθοδοι επιτελούν λειτουργίες στα αντικείμενα της κλάσης. Κάθε μέλος μίας κλάσης, είτε πεδίο είτε μέθοδος, πρoσδιορίζεται από έναν προσδιοριστή προσπέλασης (access modifier). Υπάρχουν τέσσερεις προσδιοριστές προσπέλασης: private, package-private (με κενό μετρατροπέα), protect και public. Τα private μέλη είναι ορατά μόνο από την ίδια κλάση, τα package-private είναι ορατά από κλάσεις του ίδιου πακέτου, τα protected από κλάσεις του ίδιου πακέτου και από κλάσεις εκτός πακέτου που επεκτείνουν (extends) αυτήν την κλάση, είναι δηλαδή υποκλάσεις της. Τα public μέλη είναι ορατά από όλες τις κλάσεις της εφαρμογής.  

Έστω, για παράδειγμα, ότι θέλουμε να δημιουργήσουμε μια  κλάση η οποία να παριστά  την οντότητα  "φοιτητής" (Student) . Κάθε φοιτητής θα προσδιορίζεται από  δύο πεδία, το πεδίο code (κωδικός) και το πεδίο name (όνομα). Επιπλέον, η κλάση θα περιέχει μεθόδους  για ανάγνωση και τροποποίηση των πεδίων code και name  καθώς και μεθόδους για κατασκευή νέου αντικειμένου Student (κατασκευαστές). Ο κώδικας που ακολουθεί δημιουργεί την κλάση Student και περιέχει: α) Δύο πεδία, το αριθμητικό (int) πεδίο code και το αλφαριθμητικό (String). name β) Δύο κατασκευαστές, έναν χωρίς παραμέτρους και έναν με παραμέτρους τις code και name. γ) Δύο μεθόδους λήψης της τιμής των πεδίων (getters), τις getCode() και getName. δ) Δύο μεθόδους εκχώρησης τιμής (setters) στα πεδία code και name, τις setCode() και setName(). public class Student{
    private int code;
    private String name;
    //Kατασκευαστής της κλάσης χωρίς παραμέτρους
    public Student(){
        code = 0;
        name = "";
    }
    //Kατασκευαστής της κλάσης με παραμέτρους
    public Student(int code, String name){
        this.code = code;
        this.name = name;
    }
    //Η μέθοδος επιστρέφει τον κωδικό
    public int getCode(){
        return code;
    }
    //Η μέθοδος επιστρέφει το όνομα
    public String getName(){
        return name;
    }
    //Η μέθοδος θέτει κωδικό σε ένα αντικείμενο
    public void setCode(int code){
        this.code = code;
    }
    //Η μέθοδος θέτει όνομα σε ένα αντικείμενο
    public void setName(String name){
        this.name = name;
    }
}

 Εργαλεία ανάπτυξης 

Όλα τα εργαλεία που χρειάζεται κάποιος για να γράψει Java προγράμματα έρχονται δωρεάν, από το περιβάλλον ανάπτυξης μέχρι εργαλεία build όπως το Apache Ant και βιβλιοθήκες, ενώ υπάρχουν πολλές διαφορετικές υλοποιήσεις της Εικονικής Μηχανής και του μεταγλωττιστή (π.χ. the GNU Compiler for Java) της Java.

Πολλά εργαλεία και τεχνολογίες σε Java μπορούν να βρεθούν στο Apache Software Foundation αλλά και στο Jakarta Project.

 Ολοκληρωμένο περιβάλλον ανάπτυξης (IDE) 

Για να να γράψει κάποιος κώδικα Java δε χρειάζεται τίποτα άλλο παρά έναν επεξεργαστή κειμένου, όπως το Σημειωματάριο (Notepad) των Windows ή ο vi (γνωστός στο χώρο του Unix). Παρόλ' αυτά, ένα ολοκληρωμένο περιβάλλον ανάπτυξης (IDE) βοηθάει πολύ, ιδιαίτερα στον εντοπισμό σφαλμάτων (debugging). Υπάρχουν αρκετά διαθέσιμα IDEs, ενώ πολλά από αυτά παρέχονται δωρεάν. Τα πιο γνωστά Ολοκληρωμένα Περιβάλλοντα Ανάπτυξης είναι το NetBeans της Apache, το Eclipse και το IntelliJ Idea της JetBrains. 

 Δείτε επίσης 
 JAR
 Java Platform, Enterprise Edition
Παραπομπές

 Πηγές 
 Cay S. Horstmann «Core Java, Volume I - Fundamentals» Tenth Edition, December 2015.
Daniel Y. Liang "Introduction to JAVA programming and data structures" Twelfth Edition, 2020

 Εξωτερικοί σύνδεσμοι 

 Java Tutorial , 
 Community , 

 IDE 
 NetBeans , 
 Eclipse , 
 jΕdit , 
 JCreator  
 JΒuilder
 IntelliJ IDEA

 Ομάδες χρηστών Java (User Groups) 
 jugs κοινότητα
 jhug (ελληνική ομάδα χρηστών Java)
 bejug (βελγική ομάδα χρηστών Java)
 jugmilano (μιλανέζικη ομάδα χρηστών Java)
 egjug (αιγυπτιακή ομάδα χρηστών Java)


Κατηγορία:Διαδικαστικές γλώσσες προγραμματισμού
Κατηγορία:Αντικειμενοστρεφείς γλώσσες προγραμματισμού
Κατηγορία:Επιστήμη υπολογιστών