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

Πώς να περιγράψετε τον κώδικα Java με σχολιασμούς

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

Πριν από την Java 5, τα σχόλια ήταν ο μόνος ευέλικτος μηχανισμός που η Java είχε να προσφέρει για τη σύνδεση μεταδεδομένων με στοιχεία εφαρμογής. Ωστόσο, τα σχόλια είναι κακή επιλογή. Επειδή ο μεταγλωττιστής τους αγνοεί, τα σχόλια δεν είναι διαθέσιμα κατά το χρόνο εκτέλεσης. Και ακόμη και αν ήταν διαθέσιμα, το κείμενο θα πρέπει να αναλυθεί για να ληφθούν κρίσιμα στοιχεία δεδομένων. Χωρίς τυποποίηση του τρόπου προσδιορισμού των στοιχείων δεδομένων, αυτά τα στοιχεία ενδέχεται να αποδειχθούν αδύνατα να αναλυθούν.

λήψη Λήψη του κώδικα Λήψη του πηγαίου κώδικα για παραδείγματα σε αυτό το πρόγραμμα εκμάθησης Java 101. Δημιουργήθηκε από τον Jeff Friesen για.

Μη τυπικοί μηχανισμοί σχολιασμού

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

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

  • Ενα @διεπαφή μηχανισμός για τη δήλωση τύπων σχολιασμών.
  • Τύποι μετα-σχολιασμού, τους οποίους μπορείτε να χρησιμοποιήσετε για να προσδιορίσετε τα στοιχεία εφαρμογής στα οποία ισχύει ένας τύπος σχολιασμού. για να προσδιορίσετε τη διάρκεια ζωής ενός σχόλιο (μια παρουσία τύπου σχολιασμού) · κι αλλα.
  • Υποστήριξη για επεξεργασία σχολιασμών μέσω επέκτασης στο Java Reflection API (θα συζητηθεί σε μελλοντικό άρθρο), το οποίο μπορείτε να χρησιμοποιήσετε για να ανακαλύψετε τους σχολιασμούς χρόνου εκτέλεσης ενός προγράμματος και ένα γενικευμένο εργαλείο για την επεξεργασία σχολιασμών.
  • Τυπικοί τύποι σχολιασμών.

Θα εξηγήσω πώς να χρησιμοποιήσετε αυτά τα στοιχεία καθώς εργαζόμαστε σε αυτό το άρθρο.

Δήλωση τύπων σχολιασμών με το @interface

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

Λίστα 1:ThreadSafe.java

δημόσιο @interface ThreadSafe {}

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

Λίστα 2:AnnDemo.java (έκδοση 1)

δημόσια τάξη AnnDemo {@ThreadSafe public static void main (String [] args) {}}

ThreadSafe Οι παρουσίες δεν παρέχουν μεταδεδομένα εκτός από το όνομα τύπου σχολιασμού. Ωστόσο, μπορείτε να παρέχετε μεταδεδομένα προσθέτοντας στοιχεία σε αυτόν τον τύπο, όπου ένα στοιχείο είναι μια κεφαλίδα μεθόδου που τοποθετείται στο σώμα του τύπου σχολιασμού.

Εκτός από το ότι δεν έχουν σώματα κώδικα, τα στοιχεία υπόκεινται στους ακόλουθους περιορισμούς:

  • Η κεφαλίδα της μεθόδου δεν μπορεί να δηλώσει παραμέτρους.
  • Η κεφαλίδα της μεθόδου δεν μπορεί να παρέχει ρήτρα ρίψης.
  • Ο τύπος επιστροφής της κεφαλίδας μεθόδου πρέπει να είναι πρωτόγονος τύπος (π.χ. int), java.lang.String, java.lang.Class, ένα enum, έναν τύπο σχολιασμού ή μια σειρά από αυτούς τους τύπους. Δεν μπορεί να καθοριστεί άλλος τύπος για τον τύπο επιστροφής.

Ως άλλο παράδειγμα, η Λίστα 3 παρουσιάζει ένα Να κάνω τύπος σχολιασμού με τρία στοιχεία που προσδιορίζουν μια συγκεκριμένη εργασία κωδικοποίησης, προσδιορίζοντας την ημερομηνία κατά την οποία θα ολοκληρωθεί η εργασία και ορίζοντας τον κωδικοποιητή υπεύθυνο για την ολοκλήρωση της εργασίας.

Λίστα 3:ToDo.java (έκδοση 1)

δημόσιο @interface ToDo {int id (); String finishΗμερομηνία (); Κωδικοποιητής συμβολοσειράς () προεπιλογή "n / a"; }

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

Η καταχώριση 4 χρησιμοποιεί Να κάνω για να σχολιάσετε μια ατελή μέθοδο κλάσης.

Λίστα 4:AnnDemo.java (έκδοση 2)

δημόσια τάξη AnnDemo {public static void main (String [] args) {String [] city = {"New York", "Melbourne", "Beijing", "Moscow", "Paris", "London"}; ταξινόμηση (πόλεις); } @ToDo (id = 1000, finishDate = "10/10/2019", coder = "John Doe") στατικό κενό (αντικείμενο [] αντικείμενα] {}}

Η καταχώριση 4 εκχωρεί ένα στοιχείο μεταδεδομένων σε κάθε στοιχείο. για παράδειγμα, 1000 έχει ανατεθεί σε ταυτότητα. Διαφορετικός κωδικοποιητής, ο ταυτότητα και ολοκλήρωση Ημερομηνία τα στοιχεία πρέπει να καθοριστούν · Διαφορετικά, ο μεταγλωττιστής θα αναφέρει ένα σφάλμα. Πότε κωδικοποιητής δεν έχει εκχωρηθεί τιμή, υποθέτει την προεπιλεγμένη τιμή "α / α" αξία.

Η Java παρέχει ένα ειδικό Τιμή συμβολοσειράς () στοιχείο που μπορεί να χρησιμοποιηθεί για την επιστροφή μιας λίστας στοιχείων μεταδεδομένων διαχωρισμένων με κόμμα. Η λίστα 5 δείχνει αυτό το στοιχείο σε μια αναδιαμορφωμένη έκδοση του Να κάνω.

Λίστα 5:ToDo.java (έκδοση 2)

public @interface ToDo {Τιμή συμβολοσειράς (); }

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

Λίστα 6:AnnDemo.java (έκδοση 3)

δημόσια τάξη AnnDemo {public static void main (String [] args) {String [] city = {"New York", "Melbourne", "Beijing", "Moscow", "Paris", "London"}; ταξινόμηση (πόλεις); } @ToDo (value = "1000,10 / 10/2019, John Doe") είδος στατικού κενού (Object [] Objects) {} @ToDo ("1000,10 / 10/2019, John Doe") στατική boolean αναζήτηση ( Αντικείμενο [] αντικείμενα, κλειδί αντικειμένου) {return false; }}

Χρήση τύπων μετα-σχολιασμού - το πρόβλημα της ευελιξίας

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

Λίστα 7:AnnDemo.java (έκδοση 4)

@ToDo ("1000,10 / 10/2019, John Doe") δημόσια τάξη AnnDemo {public static void main (String [] args) {@ToDo (value = "1000,10 / 10/2019, John Doe") String [] πόλεις = {"Νέα Υόρκη", "Μελβούρνη", "Πεκίνο", "Μόσχα", "Παρίσι", "Λονδίνο"}; ταξινόμηση (πόλεις); } @ToDo (value = "1000,10 / 10/2019, John Doe") είδος στατικού κενού (Object [] Objects) {} @ToDo ("1000,10 / 10/2019, John Doe") στατική boolean αναζήτηση ( Αντικείμενο [] αντικείμενα, κλειδί αντικειμένου) {return false; }}

Στην καταχώριση 7, Να κάνω χρησιμοποιείται επίσης για να σχολιάσει το AnnDemo τάξη και πόλεις τοπική μεταβλητή. Η παρουσία αυτών των εσφαλμένων σχολιασμών μπορεί να προκαλέσει σύγχυση σε κάποιον που αναθεωρεί τον κώδικά σας ή ακόμα και τα δικά σας εργαλεία επεξεργασίας σχολιασμών. Για τις στιγμές που πρέπει να περιορίσετε την ευελιξία ενός τύπου σχολιασμού, η Java προσφέρει το Στόχος τύπος σχολιασμού σε αυτό java.lang.annotation πακέτο.

Στόχος είναι ένα τύπος μετα-σχολιασμού - έναν τύπο σχολιασμού του οποίου οι σχολιασμοί επισημαίνουν τους τύπους σχολιασμών, σε αντίθεση με έναν τύπο μη-σχολιασμού του οποίου οι σχολιασμοί σχολιάζουν στοιχεία εφαρμογής, όπως τάξεις και μεθόδους. Προσδιορίζει τα είδη των στοιχείων εφαρμογής στα οποία εφαρμόζεται ένας τύπος σχολιασμού. Αυτά τα στοιχεία αναγνωρίζονται από Στόχος'μικρό ElementValue [] τιμή () στοιχείο.

java.lang.annotation.ElementType είναι ένα enum του οποίου οι σταθερές περιγράφουν στοιχεία εφαρμογής. Για παράδειγμα, ΚΑΤΑΣΚΕΥΑΣΤΗΣ ισχύει για κατασκευαστές και ΠΑΡΑΜΕΤΡΟ ισχύει για παραμέτρους. Λίστα 8 αντιδραστήρων Λίστα 5 Να κάνω τύπος σχολιασμού για να τον περιορίσετε μόνο σε μεθόδους.

Λίστα 8:ToDo.java (έκδοση 3)

εισαγωγή java.lang.annotation.ElementType; εισαγωγή java.lang.annotation.Target; @Target ({ElementType.METHOD}) δημόσιο @interface ToDo {String value (); }

Δεδομένου του refactored Να κάνω τύπος σχολιασμού, μια προσπάθεια σύνταξης της καταχώρισης 7 έχει ως αποτέλεσμα το ακόλουθο μήνυμα σφάλματος:

AnnDemo.java :: σφάλμα: ο τύπος σχολιασμού δεν ισχύει για αυτό το είδος δήλωσης @ToDo ("1000,10 / 10/2019, John Doe") ^ AnnDemo.java:6: σφάλμα: ο τύπος σχολιασμού δεν ισχύει για αυτό το είδος δήλωση @ToDo (τιμή = "1000,10 / 10/2019, John Doe") ^ 2 σφάλματα

Πρόσθετοι τύποι μετα-σχολιασμού

Το Java 5 εισήγαγε τρεις επιπλέον τύπους μετα-σχολιασμού, οι οποίοι βρίσκονται στο java.lang.annotation πακέτο:

  • Κράτηση υποδεικνύει πόσο καιρό θα διατηρηθούν οι σχολιασμοί με τον σχολιασμένο τύπο. Αυτός ο τύπος σχετίζεται java.lang.annotation.RetentionPolicy Το enum δηλώνει σταθερές ΤΑΞΗ (ο μεταγλωττιστής καταγράφει σχολιασμούς σε αρχείο κλάσης. η εικονική μηχανή δεν τις διατηρεί για εξοικονόμηση μνήμης - προεπιλεγμένη πολιτική), ΔΙΑΔΙΚΑΣΙΑ (ο μεταγλωττιστής καταγράφει σχολιασμούς σε αρχείο κλάσης · ​​η εικονική μηχανή τους διατηρεί) και ΠΗΓΗ (ο μεταγλωττιστής απορρίπτει σχολιασμούς).
  • Τεκμηριωμένο υποδεικνύει ότι οι περιπτώσεις του Τεκμηριωμένο- οι σχολιασμένοι σχολιασμοί πρέπει να τεκμηριώνονται από javadoc και παρόμοια εργαλεία.
  • Κληρονόμησε υποδεικνύει ότι ένας τύπος σχολιασμού μεταβιβάζεται αυτόματα.

Η Java 8 παρουσίασε το java.lang.annotation.Repeatable τύπος μετα-σχολιασμού. Επαναληπτός χρησιμοποιείται για να δείξει ότι ο τύπος σχολιασμού του οποίου η δήλωση (μετα-) σχολιάζει είναι επαναλαμβανόμενος. Με άλλα λόγια, μπορείτε να εφαρμόσετε πολλαπλούς σχολιασμούς από τον ίδιο επαναλαμβανόμενο τύπο σχολιασμού σε ένα στοιχείο εφαρμογής, όπως φαίνεται εδώ:

@ToDo (τιμή = "1000,10 / 10/2019, John Doe") @ToDo (τιμή = "1001,10 / 10/2019, Kate Doe") είδος στατικού κενού (αντικείμενο [] αντικείμενα] {}

Αυτό το παράδειγμα υποθέτει ότι Να κάνω έχει σχολιαστεί με το Επαναληπτός τύπος σχολιασμού.

Επεξεργασία σχολιασμών

Οι σχολιασμοί προορίζονται για επεξεργασία. Διαφορετικά, δεν έχει νόημα να τα έχουμε. Το Java 5 επέκτεινε το API προβληματισμού για να σας βοηθήσει να δημιουργήσετε τα δικά σας εργαλεία επεξεργασίας σχολιασμών. Για παράδειγμα, Τάξη δηλώνει ένα Σχολιασμός [] getAnnotations () μέθοδος που επιστρέφει έναν πίνακα java.lang. Σημείωση περιπτώσεις που περιγράφουν σχολιασμούς που υπάρχουν στο στοιχείο που περιγράφεται από το Τάξη αντικείμενο.

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

Λίστα 9:AnnProcDemo.java

εισαγωγή java.lang.reflect.Method; δημόσια τάξη AnnProcDemo {public static void main (String [] args) ρίχνει την Εξαίρεση {if (args.length! = 1) {System.err.println ("use: java AnnProcDemo classfile"); ΕΠΙΣΤΡΟΦΗ; } Μέθοδος [] μεθόδους = Class.forName (args [0]). GetMethods (); για (int i = 0; i <metod.length; i ++) {if (μέθοδοι [i] .isAnnotationPresent (ToDo.class)) {ToDo todo = metod [i] .getAnnotation (ToDo.class); String [] components = todo.value (). Split (","); System.out.printf ("ID =% s% n", στοιχεία [0]); System.out.printf ("Ημερομηνία λήξης =% s% n", στοιχεία [1]); System.out.printf ("Coder =% s% n% n", στοιχεία [2]); }}}}

Αφού επαληθεύσετε ότι έχει καθοριστεί ακριβώς ένα όρισμα γραμμής εντολών (προσδιορισμός αρχείου κλάσης), κύριος() φορτώνει το αρχείο τάξης μέσω Class.forName (), επικαλείται getMethods () για να επιστρέψετε μια σειρά από java.lang.reflect.M Method αντικείμενα ταυτοποίησης όλων δημόσιο μεθόδους στο αρχείο κλάσης και επεξεργάζεται αυτές τις μεθόδους.

Η επεξεργασία της μεθόδου ξεκινά με την επίκληση Μέθοδος'μικρό boolean isAnnotationPresent (Class annotationClass) μέθοδος για να προσδιοριστεί εάν ο σχολιασμός που περιγράφεται από το ToDo.class υπάρχει στη μέθοδο. Αν είναι έτσι, Μέθοδος'μικρό T getAnnotation (Class annotationClass) καλείται μέθοδος για να λάβετε τον σχολιασμό.

ο Να κάνω Οι σχολιασμοί που υποβάλλονται σε επεξεργασία είναι εκείνοι των οποίων οι τύποι δηλώνουν ένα Τιμή συμβολοσειράς () στοιχείο (βλ. Καταχώριση 5). Επειδή τα μεταδεδομένα που βασίζονται σε συμβολοσειρά αυτού του στοιχείου διαχωρίζονται με κόμμα, πρέπει να χωριστούν σε έναν πίνακα τιμών στοιχείων. Έπειτα προσπελάζεται και εξάγεται κάθε μία από τις τρεις τιμές συνιστωσών.

Συντάξτε αυτόν τον πηγαίο κώδικα (javac AnnProcDemo.java). Προτού μπορέσετε να εκτελέσετε την εφαρμογή, θα χρειαστείτε ένα κατάλληλο αρχείο τάξης με @Να κάνω σχολιασμοί σε αυτό δημόσιο μεθόδους. Για παράδειγμα, μπορείτε να τροποποιήσετε την καταχώριση 6 Ανντέμο πηγαίος κώδικας για συμπερίληψη δημόσιο μέσα στο είδος() και Αναζήτηση() κεφαλίδες μεθόδου. Θα χρειαστείτε επίσης την καταχώριση 10's Να κάνω τύπος σχολιασμού, ο οποίος απαιτεί το ΔΙΑΔΙΚΑΣΙΑ πολιτική διατήρησης.

Λίστα 10:ToDo.java (έκδοση 4)

εισαγωγή java.lang.annotation.ElementType; εισαγωγή java.lang.annotation.Retention; εισαγωγή java.lang.annotation.RetentionPolicy; εισαγωγή java.lang.annotation.Target; @Target ({ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) public @interface ToDo {String value (); }

Μεταγλώττιση των τροποποιημένων AnnDemo.java και Λίστα 10 και εκτελέστε την ακόλουθη εντολή για επεξεργασία Ανντέμο'μικρό Να κάνω σχολιασμοί:

java AnnProcDemo AnnDemo

Εάν όλα πάνε καλά, θα πρέπει να παρατηρήσετε την ακόλουθη έξοδο:

ID = 1000 Ημερομηνία λήξης = 10/10/2019 Coder = John Doe ID = 1000 Ημερομηνία λήξης = 10/10/2019 Coder = John Doe

Επεξεργασία σχολίων με apt και τον μεταγλωττιστή Java

Η Java 5 εισήγαγε ένα κατάλληλος εργαλείο για την επεξεργασία σχολιασμών με γενικευμένο τρόπο. Η Java 6 μετεγκαταστάθηκε κατάλληλοςΛειτουργικότητα σε αυτό javac εργαλείο μεταγλώττισης και το Java 7 καταργήθηκε κατάλληλος, το οποίο στη συνέχεια αφαιρέθηκε (ξεκινώντας με Java 8).

Τυπικοί τύποι σχολιασμών

Μαζί με Στόχος, Κράτηση, Τεκμηριωμένο, και Κληρονόμησε, Java 5 εισήχθη java.lang. Καταργήθηκε, java.lang.Παράλειψη, και java.lang.SuppressWarnings. Αυτοί οι τρεις τύποι σχολιασμών έχουν σχεδιαστεί για χρήση μόνο σε περιβάλλον μεταγλωττιστή, γι 'αυτό ορίζονται οι πολιτικές διατήρησής τους ΠΗΓΗ.

Καταργήθηκε