Προγραμματισμός

Ο τρόπος ζωής αρχείων κατηγορίας Java

Καλώς ήλθατε σε μια άλλη δόση του "Under the Hood". Στο άρθρο του περασμένου μήνα συζήτησα την Java Virtual Machine, ή JVM, τον αφηρημένο υπολογιστή για τον οποίο συντάσσονται όλα τα προγράμματα Java. Εάν δεν είστε εξοικειωμένοι με το JVM, ίσως θελήσετε να διαβάσετε το άρθρο του προηγούμενου μήνα πριν από αυτό. Σε αυτό το άρθρο δίνω μια ματιά στη βασική δομή και τον τρόπο ζωής του αρχείου κλάσης Java.

Γεννήθηκε για να ταξιδέψει

Το αρχείο κλάσης Java είναι μια ακριβής καθορισμένη μορφή για μεταγλωττισμένη Java. Ο πηγαίος κώδικας Java συγκεντρώνεται σε αρχεία κλάσης που μπορούν να φορτωθούν και να εκτελεστούν από οποιοδήποτε JVM. Τα αρχεία τάξης ενδέχεται να ταξιδεύουν σε ένα δίκτυο πριν από τη φόρτωσή τους από το JVM.

Στην πραγματικότητα, εάν διαβάζετε αυτό το άρθρο μέσω προγράμματος περιήγησης με δυνατότητα Java, τα αρχεία τάξης για τη μικροεφαρμογή προσομοίωσης στο τέλος του άρθρου μεταφέρονται μέσω Διαδικτύου στον υπολογιστή σας αυτήν τη στιγμή. Εάν θέλετε να τα ακούσετε (και ο υπολογιστής σας διαθέτει δυνατότητα ήχου), πατήστε το παρακάτω κουμπί:

Χρειάζεστε ένα πρόγραμμα περιήγησης με δυνατότητα Java για να δείτε αυτό το applet

Ακούγεται σαν να διασκεδάζουν, ε; Αυτό είναι στη φύση τους. Τα αρχεία κατηγορίας Java σχεδιάστηκαν για να ταξιδεύουν καλά. Είναι ανεξάρτητες από την πλατφόρμα, οπότε θα είναι ευπρόσδεκτες σε περισσότερα μέρη. Περιέχουν bytecodes, το συμπαγές σετ εντολών για το JVM, ώστε να μπορούν να ταξιδεύουν στο φως. Τα αρχεία κλάσης Java πραγματοποιούν συνεχώς μετακίνηση μέσω δικτύων με ταχύτατη ταχύτητα για να φτάσουν σε JVM σε όλο τον κόσμο.

Τι υπάρχει σε ένα αρχείο τάξης;

Το αρχείο κλάσης Java περιέχει όλα όσα χρειάζεται να γνωρίζει ένα JVM για μία τάξη ή διεπαφή Java. Με τη σειρά εμφάνισής τους στο αρχείο κλάσης, τα κύρια στοιχεία είναι: μαγεία, έκδοση, συνεχής συγκέντρωση, σημαίες πρόσβασης, αυτή η τάξη, σούπερ κλάση, διεπαφές, πεδία, μέθοδοι και χαρακτηριστικά.

Οι πληροφορίες που αποθηκεύονται στο αρχείο κλάσης ποικίλλουν συχνά σε μήκος - δηλαδή, το πραγματικό μήκος των πληροφοριών δεν μπορεί να προβλεφθεί πριν από τη φόρτωση του αρχείου κλάσης. Για παράδειγμα, ο αριθμός των μεθόδων που αναφέρονται στο στοιχείο μεθόδων μπορεί να διαφέρει μεταξύ των αρχείων κλάσης, επειδή εξαρτάται από τον αριθμό των μεθόδων που ορίζονται στον πηγαίο κώδικα. Τέτοιες πληροφορίες οργανώνονται στο αρχείο τάξης με την εισαγωγή των πραγματικών πληροφοριών από το μέγεθος ή το μήκος της. Με αυτόν τον τρόπο, όταν η τάξη φορτώνεται από το JVM, διαβάζεται πρώτα το μέγεθος των πληροφοριών μεταβλητού μήκους. Μόλις το JVM γνωρίσει το μέγεθος, μπορεί να διαβάσει σωστά τις πραγματικές πληροφορίες.

Οι πληροφορίες εγγράφονται γενικά στο αρχείο τάξης χωρίς κενό ή παραγέμισμα μεταξύ διαδοχικών πληροφοριών. όλα είναι ευθυγραμμισμένα με όρια byte. Αυτό βοηθά να διατηρείτε τα αρχεία της τάξης μικρά, έτσι ώστε να είναι αεροδυναμικά καθώς πετούν σε δίκτυα.

Η σειρά των συστατικών αρχείων κατηγορίας ορίζεται αυστηρά, ώστε οι JVM να μπορούν να γνωρίζουν τι να περιμένουν και πού να το περιμένουν, κατά τη φόρτωση ενός αρχείου κλάσης. Για παράδειγμα, κάθε JVM γνωρίζει ότι τα πρώτα οκτώ byte ενός αρχείου κλάσης περιέχουν τους μαγικούς αριθμούς και τους αριθμούς έκδοσης, ότι η συνεχής συγκέντρωση ξεκινά από το ένατο byte και ότι οι σημαίες πρόσβασης ακολουθούν τη σταθερή ομάδα. Αλλά επειδή η σταθερή ομάδα είναι μεταβλητού μήκους, δεν γνωρίζει την ακριβή τοποθεσία των σημαιών πρόσβασης έως ότου ολοκληρωθεί η ανάγνωση στη σταθερή ομάδα. Μόλις τελειώσει η ανάγνωση στη συνεχή ομάδα, γνωρίζει ότι τα επόμενα δύο byte θα είναι οι σημαίες πρόσβασης.

Magic και αριθμοί έκδοσης

Τα πρώτα τέσσερα byte κάθε αρχείου τάξης είναι πάντα 0xCAFEBABE. Αυτός ο μαγικός αριθμός κάνει τα αρχεία κλάσης Java ευκολότερα στην αναγνώρισή τους, επειδή οι πιθανότητες είναι μικρές που τα αρχεία εκτός κλάσης θα ξεκινούσαν με τα ίδια αρχικά τέσσερα byte. Ο αριθμός ονομάζεται μαγικός επειδή μπορεί να τραβηχτεί από ένα καπέλο από τους σχεδιαστές μορφών αρχείων. Η μόνη απαίτηση είναι ότι δεν χρησιμοποιείται ήδη από άλλη μορφή αρχείου που μπορεί να συναντηθεί στον πραγματικό κόσμο. Σύμφωνα με τον Patrick Naughton, βασικό μέλος της αρχικής ομάδας της Java, ο μαγικός αριθμός επιλέχθηκε "πολύ πριν το όνομα Java εκφωνηθεί ποτέ σε σχέση με αυτήν τη γλώσσα. Ψάχναμε κάτι διασκεδαστικό, μοναδικό και εύκολο να θυμόμαστε. Είναι μόνο μια σύμπτωση ότι το OxCAFEBABE, μια λοξή αναφορά στα χαριτωμένα baristas στο Peet's Coffee, προκάλεσε το όνομα Java. "

Τα δεύτερα τέσσερα byte του αρχείου κλάσης περιέχουν τους κύριους και δευτερεύοντες αριθμούς έκδοσης. Αυτοί οι αριθμοί προσδιορίζουν την έκδοση της μορφής αρχείου κλάσης στην οποία τηρείται ένα συγκεκριμένο αρχείο κλάσης και επιτρέπουν στα JVM να επαληθεύουν ότι το αρχείο κλάσης είναι φορτώσιμο. Κάθε JVM έχει τη μέγιστη έκδοση που μπορεί να φορτώσει και τα JVM θα απορρίψουν αρχεία κλάσης με νεότερες εκδόσεις.

Σταθερή πισίνα

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

Η σταθερή ομάδα οργανώνεται ως μια σειρά στοιχείων μεταβλητού μήκους. Κάθε σταθερά καταλαμβάνει ένα στοιχείο στον πίνακα. Σε ολόκληρο το αρχείο κλάσης, οι σταθερές αναφέρονται από τον ακέραιο ευρετήριο που δείχνει τη θέση τους στον πίνακα. Η αρχική σταθερά έχει δείκτη ενός, η δεύτερη σταθερά έχει δείκτη δύο κ.λπ. Ο πίνακας σταθερής συγκέντρωσης προηγείται από το μέγεθος του πίνακα, έτσι ώστε οι JVM να γνωρίζουν πόσες σταθερές θα περιμένουν κατά τη φόρτωση του αρχείου κλάσης.

Κάθε στοιχείο της σταθερής δεξαμενής ξεκινά με μια ετικέτα ενός byte που καθορίζει τον τύπο της σταθεράς σε αυτήν τη θέση στον πίνακα. Μόλις ένα JVM πιάσει και ερμηνεύσει αυτήν την ετικέτα, ξέρει τι ακολουθεί την ετικέτα. Για παράδειγμα, εάν μια ετικέτα δηλώνει ότι η σταθερά είναι συμβολοσειρά, η JVM αναμένει ότι τα επόμενα δύο byte θα έχουν το μήκος της συμβολοσειράς. Μετά από αυτό το μήκος δύο byte, η JVM αναμένει να βρει μήκος αριθμός byte, που αποτελούν τους χαρακτήρες της συμβολοσειράς.

Στο υπόλοιπο του άρθρου, μερικές φορές θα αναφερθώ στο ένατο στοιχείο της συστοιχίας σταθερού συνόλου ως const_pool [n]. Αυτό έχει νόημα στο βαθμό που η σταθερή ομάδα είναι οργανωμένη σαν πίνακας, αλλά λάβετε υπόψη ότι αυτά τα στοιχεία έχουν διαφορετικά μεγέθη και τύπους και ότι το πρώτο στοιχείο έχει δείκτη ενός.

Πρόσβαση σε σημαίες

Τα δύο πρώτα byte μετά τη συνεχή συγκέντρωση, οι σημαίες πρόσβασης, υποδεικνύουν εάν αυτό το αρχείο ορίζει μια κλάση ή μια διεπαφή, είτε η κλάση ή η διεπαφή είναι δημόσια είτε αφηρημένη και (εάν είναι κλάση και όχι διεπαφή) εάν είναι τελικό.

Αυτή η τάξη

Τα επόμενα δύο byte, το αυτή η τάξη συστατικό στοιχείο, είναι ένας δείκτης στη συστοιχία σταθερού συνόλου. Η σταθερά στην οποία αναφέρεται αυτή η τάξη, stable_pool [this_class], έχει δύο μέρη, μια ετικέτα ενός byte και ένα ευρετήριο ονόματος δύο byte. Η ετικέτα θα ισούται με CONSTANT_Class, μια τιμή που υποδεικνύει ότι αυτό το στοιχείο περιέχει πληροφορίες σχετικά με μια κλάση ή διεπαφή. Το Constant_pool [name_index] είναι μια σταθερά συμβολοσειράς που περιέχει το όνομα της κλάσης ή της διεπαφής.

ο αυτή η τάξη Το στοιχείο παρέχει μια ματιά στον τρόπο χρήσης της σταθερής δεξαμενής. Αυτή η τάξη ο ίδιος είναι απλά ένας δείκτης στη συνεχή συγκέντρωση. Όταν ένα JVM αναζητά το stable_pool [this_class], βρίσκει ένα στοιχείο που αναγνωρίζεται ως CONSTANT_Class με την ετικέτα του. Το JVM γνωρίζει ότι τα στοιχεία CONSTANT_Class έχουν πάντα ένα ευρετήριο δύο byte στη σταθερή ομάδα, που ονομάζεται ευρετήριο ονόματος, ακολουθώντας την ετικέτα ενός byte. Ψάχνει λοιπόν το stable_pool [name_index] για να πάρει τη συμβολοσειρά που περιέχει το όνομα της κλάσης ή της διεπαφής.

Σούπερ τάξη

Σε συνέχεια του αυτή η τάξη το στοιχείο είναι το σούπερ τάξη συστατικό στοιχείο, ένας άλλος δείκτης δύο byte στη σταθερή ομάδα. Το Constant_pool [super_class] είναι ένα στοιχείο CONSTANT_Class που δείχνει το όνομα της σούπερ κλάσης από την οποία κατεβαίνει αυτή η τάξη.

Διεπαφές

Το στοιχείο διεπαφών ξεκινά με μια μέτρηση δύο byte του αριθμού των διεπαφών που εφαρμόζονται από την κλάση (ή διεπαφή) που ορίζεται στο αρχείο. Αμέσως μετά ακολουθεί ένας πίνακας που περιέχει ένα ευρετήριο στη σταθερή ομάδα για κάθε διεπαφή που εφαρμόζεται από την κλάση. Κάθε διεπαφή αντιπροσωπεύεται από ένα στοιχείο CONSTANT_Class στη σταθερή ομάδα που δείχνει το όνομα της διεπαφής.

Πεδία

Το στοιχείο πεδίων ξεκινά με μια μέτρηση δύο byte του αριθμού των πεδίων σε αυτήν την τάξη ή διεπαφή. Ένα πεδίο είναι μια παρουσία ή μεταβλητή κλάσης της κλάσης ή της διεπαφής. Μετά την καταμέτρηση είναι ένας πίνακας δομών μεταβλητού μήκους, ένας για κάθε πεδίο. Κάθε δομή αποκαλύπτει πληροφορίες για ένα πεδίο, όπως το όνομα, τον τύπο και, εάν είναι μια τελική μεταβλητή, η σταθερή του τιμή. Ορισμένες πληροφορίες περιέχονται στην ίδια τη δομή και μερικές περιέχονται σε σταθερές θέσεις συγκέντρωσης που υποδεικνύονται από τη δομή.

Τα μόνα πεδία που εμφανίζονται στη λίστα είναι εκείνα που δηλώθηκαν από την κλάση ή τη διεπαφή που ορίζεται στο αρχείο. στη λίστα δεν εμφανίζονται κληρονομικά πεδία από super class ή superinterfaces.

Μέθοδοι

Η συνιστώσα μεθόδων ξεκινά με μια μέτρηση δύο byte του αριθμού των μεθόδων στην τάξη ή τη διεπαφή. Αυτή η μέτρηση περιλαμβάνει μόνο εκείνες τις μεθόδους που καθορίζονται ρητά από αυτήν την τάξη και όχι μεθόδους που μπορεί να κληρονομηθούν από τα superclasses. Ακολουθώντας τη μέτρηση μεθόδων είναι οι ίδιες οι μέθοδοι.

Η δομή για κάθε μέθοδο περιέχει πολλά στοιχεία σχετικά με τη μέθοδο, συμπεριλαμβανομένου του περιγραφέα μεθόδου (ο τύπος επιστροφής και η λίστα ορισμάτων), ο αριθμός των λέξεων στοίβας που απαιτούνται για τις τοπικές μεταβλητές της μεθόδου, ο μέγιστος αριθμός απαιτούμενων λέξεων στοίβας για τον τελεστή της μεθόδου στοίβα, έναν πίνακα εξαιρέσεων που πιάστηκε από τη μέθοδο, την ακολουθία bytecode και έναν πίνακα αριθμών γραμμής.

Γνωρίσματα

Αναπτύσσοντας το πίσω μέρος είναι τα χαρακτηριστικά, τα οποία παρέχουν γενικές πληροφορίες σχετικά με τη συγκεκριμένη κλάση ή διεπαφή που ορίζεται από το αρχείο. Η ενότητα χαρακτηριστικών έχει μια μέτρηση δύο byte του αριθμού των χαρακτηριστικών, ακολουθούμενη από τα ίδια τα χαρακτηριστικά. Για παράδειγμα, ένα χαρακτηριστικό είναι το χαρακτηριστικό πηγαίου κώδικα. αποκαλύπτει το όνομα του αρχείου προέλευσης από το οποίο δημιουργήθηκε αυτό το αρχείο κλάσης. Οι JVM θα αγνοήσουν σιωπηλά τυχόν χαρακτηριστικά που δεν αναγνωρίζουν.

Φόρτωση: μια προσομοίωση ενός αρχείου τάξης που φτάνει στον προορισμό του JVM

Η παρακάτω εφαρμογή προσομοιώνει ένα JVM που φορτώνει ένα αρχείο κλάσης. Το αρχείο κλάσης που φορτώνεται στην προσομοίωση δημιουργήθηκε από τον μεταγλωττιστή javac με τον ακόλουθο πηγαίο κώδικα Java:

class Act {public static void doMathForever () {int i = 0; ενώ (true) {i + = 1; i * = 2; }}} 

Το παραπάνω απόσπασμα κώδικα προέρχεται από το άρθρο του περασμένου μήνα σχετικά με την JVM. Είναι η ίδια μέθοδος doMathForever () που εκτελέστηκε από το applet EternalMath από το άρθρο του περασμένου μήνα. Επέλεξα αυτόν τον κωδικό για να δώσω ένα πραγματικό παράδειγμα που δεν ήταν πολύ περίπλοκο. Αν και ο κώδικας μπορεί να μην είναι πολύ χρήσιμος στον πραγματικό κόσμο, μεταγλωττίζεται σε ένα αρχείο πραγματικής κλάσης, το οποίο φορτώνεται από την παρακάτω προσομοίωση.

Η μικροεφαρμογή GettingLoaded σάς επιτρέπει να οδηγήσετε την προσομοίωση φόρτωσης τάξης ένα βήμα τη φορά. Για κάθε βήμα στην πορεία μπορείτε να διαβάσετε για το επόμενο κομμάτι byte που πρόκειται να καταναλωθεί και να ερμηνευτεί από το JVM. Απλώς πατήστε το κουμπί "Βήμα" για να αναγκάσετε το JVM να καταναλώσει το επόμενο κομμάτι. Πατώντας "Πίσω" θα αναιρεθεί το προηγούμενο βήμα και πατώντας "Επαναφορά" θα επαναφέρετε την προσομοίωση στην αρχική της κατάσταση, επιτρέποντάς σας να ξεκινήσετε από την αρχή.

Το JVM εμφανίζεται κάτω αριστερά καταναλώνοντας τη ροή byte που αποτελεί το αρχείο κλάσης Act.class. Τα byte εμφανίζονται σε δεκαεξαδική ροή από έναν διακομιστή κάτω δεξιά. Τα byte ταξιδεύουν δεξιά προς αριστερά, μεταξύ του διακομιστή και του JVM, ένα κομμάτι κάθε φορά. Τα κομμάτια byte που καταναλώνονται από το JVM στο επόμενο πάτημα του κουμπιού "Βήμα" εμφανίζονται με κόκκινο χρώμα. Αυτά τα επισημασμένα bytes περιγράφονται στη μεγάλη περιοχή κειμένου πάνω από το JVM. Τυχόν εναπομείναντα byte πέρα ​​από το επόμενο κομμάτι εμφανίζονται με μαύρο.

Προσπάθησα να εξηγήσω πλήρως κάθε κομμάτι byte στην περιοχή κειμένου. Υπάρχουν πολλές λεπτομέρειες, επομένως, στην περιοχή κειμένου και ίσως θελήσετε να διαβάσετε πρώτα όλα τα βήματα για να πάρετε τη γενική ιδέα και, στη συνέχεια, αναζητήστε περισσότερες λεπτομέρειες.

Καλό κλικ.

Χρειάζεστε ένα πρόγραμμα περιήγησης με δυνατότητα Java για να δείτε αυτό το applet.

Κάντε κλικ εδώ για τον πηγαίο κώδικα του GettingLoaded. Για να εκτελέσετε αυτό το applet μόνοι σας, θα χρειαστείτε επίσης τα δύο αρχεία που ανακτά αυτό το applet από το διακομιστή, το αρχείο ASCII που περιέχει το κείμενο για κάθε βήμα και το ίδιο το αρχείο Act.class. Κάντε κλικ εδώ για τον πηγαίο κώδικα της μικροεφαρμογής αρχείων Flying Class Files.

ΤΕΛΟΣ: Η μικρή εκτύπωση: "The Java Class File Lifestyle" Άρθρο Πνευματικά δικαιώματα (γ) 1996 Bill Venners. Ολα τα δικαιώματα διατηρούνται. Applet "GettingLoaded" Copyright (c) 1996 Artima Software Company. Ολα τα δικαιώματα διατηρούνται.

: END_ENDNOTE

Ο Bill Venners είναι πρόεδρος της Artima Software Company. Μέσω της Artima, κάνει προσαρμοσμένη ανάπτυξη λογισμικού και συμβουλευτικές υπηρεσίες.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Η Java Virtual Machine Specification, η επίσημη λέξη από την Sun.

    //java.sun.com/1.0alpha3/doc/vmspec/vmspec_1.html

  • Όταν βγει, το βιβλίο Η προδιαγραφή εικονικής μηχανής Java, //www.aw.com/cp/lindholm-yellin.html, από τους Tim Lindholm και Frank Yellin (ISBN 0-201-63452-X), μέρος της σειράς Java, //www.aw.com/cp/ javaseries.html), από το Addison-Wesley, πιθανότατα θα είναι ο καλύτερος πόρος JVM.
  • Ένα σχέδιο του κεφαλαίου 4 της Η προδιαγραφή εικονικής μηχανής Java, η οποία περιγράφει τη μορφή αρχείου κλάσης και τον επαληθευτή bytecode, μπορεί να ανακτηθεί από το JavaSoft.

    //java.sun.com/java.sun.com/newdocs.html

Αυτή η ιστορία, "Ο τρόπος ζωής αρχείων κατηγορίας Java" δημοσιεύθηκε αρχικά από το JavaWorld.