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

Επιλογές javac -Xlint

Ο μεταγλωττιστής γλώσσας προγραμματισμού Java (javac) που παρέχεται από την Oracle (και παλαιότερα από την Sun) έχει πολλές μη τυπικές επιλογές που είναι συχνά χρήσιμες. Ένα από τα πιο χρήσιμα είναι το σύνολο των μη τυπικών επιλογών που εκτυπώνουν προειδοποιήσεις που συναντήθηκαν κατά τη συλλογή. Αυτό το σύνολο επιλογών είναι το αντικείμενο αυτής της ανάρτησης.

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

Μια λίστα με αυτές τις επιλογές είναι επίσης διαθέσιμη από τη γραμμή εντολών (υποθέτοντας ότι το Java SDK είναι εγκατεστημένο) με την εντολή: javac -help -X. Αυτό είναι πιο σύντομο από το παράδειγμα της αρχικής σελίδας / ιστοσελίδας που φαίνεται παραπάνω και εμφανίζεται στη συνέχεια.

Όπως το προηγούμενο στιγμιότυπο από την εκτέλεση javac -help -X υποδεικνύει, οι δέκα συγκεκριμένες συνθήκες για τις οποίες υπάρχουν προειδοποιήσεις Xlint είναι (με αλφαβητική σειρά): εκμαγείο, απόσυρση, divzero, αδειάζω, πρωτοπορία, τελικά, παρακάμπτει, μονοπάτι, κατα συρροη, και ανεξέλεγκτος. Κοιτάζω εν συντομία καθένα από αυτά και παρέχω ένα απόσπασμα κώδικα που οδηγεί σε αυτές τις προειδοποιήσεις να συμβαίνουν όταν το Xlint είναι ενεργοποιημένο. Σημειώστε ότι η αρχική σελίδα για το javac και η σελίδα Java SE 6 javac παραθέτουν μόνο τις μισές από αυτές τις επιλογές Xlint (η τεκμηρίωση δεν φαίνεται να είναι τόσο ενημερωμένη όσο η χρήση / βοήθεια javac). Υπάρχει μια χρήσιμη καταχώρηση στο NetBeans Wiki που συνοψίζει και τις δέκα επιλογές.

Ο μεταγλωττιστής javac επιτρέπει όλες ή καμία από τις προειδοποιήσεις Xlint να είναι ενεργοποιημένη. Εάν το Xlint δεν έχει καθοριστεί καθόλου στην επιλογή -Xlint: κανένα δεν προσδιορίζεται ρητά, η συμπεριφορά είναι να μην εμφανίζονται οι περισσότερες από τις προειδοποιήσεις. Είναι ενδιαφέρον ότι η έξοδος παρέχει μια προειδοποίηση σχετικά με την απόσυρση και τις μη ελεγμένες προειδοποιήσεις και συνιστά την εκτέλεση javac με ενεργοποιημένο το -Xlint για να δείτε τις λεπτομέρειες σχετικά με αυτούς τους δύο τύπους προειδοποιήσεων.

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

Όπως δείχνει η παραπάνω εικόνα, εάν το Xlint δεν έχει καθοριστεί καθόλου ή έχει καθοριστεί ρητά με "κανένα", το αποτέλεσμα είναι το ίδιο: η πλειονότητα των προειδοποιήσεων δεν εμφανίζεται, αλλά υπάρχουν απλές αναφορές στην απόσυρση και στις μη ελεγμένες προειδοποιήσεις με προτάσεις για να εκτελέσετε javac με -Xlint: deprecation και -Xlint: unchecked αντίστοιχα για επιπλέον λεπτομέρειες. Εκτελώντας το javac με -Xlint: all or -Xlint χωρίς άλλες επιλογές θα εμφανιστούν όλες οι προειδοποιήσεις και θα λειτουργούσαν για να δουν τις λεπτομέρειες σχετικά με καταργημένες, μη ελεγμένες και όλες τις άλλες ισχύουσες προειδοποιήσεις με δυνατότητα Xlint. Αυτό θα εμφανιστεί αφού περάσετε από τον πηγαίο κώδικα και κάθε προειδοποίηση Xlint ξεχωριστά.

-Xlint: cast

Αυτή η επιλογή μπορεί να χρησιμοποιηθεί για να κάνει ο μεταγλωττιστής να προειδοποιήσει τον προγραμματιστή ότι δημιουργείται ένα πλεονάζον cast. Ακολουθεί ένα απόσπασμα κώδικα που θα επισημάνθηκε εάν -Xlint, -Xlint: all ή -Xlint: cast παρέχεται στο javac κατά τη σύνταξη της πηγής.

/ ** * Επίδειξη -Xlint: προειδοποίηση cast για περιττό cast. * / private static void demonstrCastWarning () {final Set people = new HashSet (); people.add (fred); people.add (wilma); people.add (barney); για (τελικό άτομο: άτομα) {// Ελεύθερος παίκτης επειδή ο γενικός τύπος είναι ρητά το Person out.println ("Person:" + ((Person) person) .getFullName ()); }} 

Στον παραπάνω κώδικα, δεν υπάρχει λόγος να μεταδώσετε το αντικείμενο του ατόμου μέσα στο βρόχο στο Person και το -Xlint: Το cast θα προειδοποιήσει για αυτό το περιττό και περιττό cast με ένα μήνυμα που θα αναφέρει κάτι σαν:

src \ dustin \ example \ Main.java: 37: προειδοποίηση: [cast] περιττό cast to dustin.examples.Person out.println ("Person:" + ((Person) person) .getFullName ()); ^ 

-Xlint: απόσυρση

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

/ ** * Αιτία -Xlint: κατάργηση εκτύπωσης προειδοποίησης σχετικά με τη χρήση της καταργημένης μεθόδου. * / private static void demonstrDeprecationWarning () {out.println ("Το πλήρες όνομα του Fred είναι" + fred.getName ()); } 

Δεν μπορείτε να πείτε χωρίς τον πηγαίο κώδικα για την κλάση Person (της οποίας το "fred" είναι μια παρουσία), αλλά αυτή η μέθοδος getName () έχει καταργηθεί στο Person. Η ακόλουθη έξοδος από την εκτέλεση javac με -Xlint, -Xlint: all ή -Xlint: deprecation επιβεβαιώνει ότι (ή το επισημαίνει εάν ο προγραμματιστής το έχασε).

src \ dustin \ example \ Main.java: 47: προειδοποίηση: [deprecation] getName () in dustin.examples.Person έχει καταργηθεί.println ("Το πλήρες όνομα του Fred είναι" + fred.getName ()); ^ 

-Xlint: divzero

Η επιλογή divzero Xlint υποδεικνύει πότε η ολοκληρωμένη διαίρεση διαιρείται με ένα κυριολεκτικό μηδέν. Ένα παράδειγμα κώδικα που θα το αποδείξει εμφανίζεται παρακάτω:

/ ** * Επίδειξη -Xlint: divzero σε δράση διαιρώντας ένα int με ένα κυριολεκτικό μηδέν. * / private static void demonstrDivideByZeroWarning () {out.println ("Two split by zero is" + divideIntegerByZeroForLongQuotient (2)); } / ** * Χωρίστε το παρεχόμενο διαιρέτη στο παρεχόμενο μέρισμα και επιστρέψτε το * προκύπτον πηλίκο. Δεν γίνονται έλεγχοι για να διασφαλιστεί ότι ο διαιρέτης δεν είναι μηδενικός. * * @param dividend Integer για διαίρεση. * @return Ποσοστό διαίρεσης μερίσματος κατά κυριολεκτικά μηδέν. * / private static long divideIntegerByZeroForLongQuotient (final int dividend) {// Ο κωδικοποιητής διακριτής μηδέν θα οδηγήσει σε προειδοποίηση. Εάν ο διαιρέτης // είχε περάσει ως παράμετρος με μηδενική τιμή, αυτό δεν θα οδηγούσε σε // αυτήν την προειδοποίηση. μέρισμα επιστροφής / 0; } 

Η έξοδος από το javac όταν μεταγλωττίζεται τα παραπάνω εμφανίζεται τώρα.

src \ dustin \ example \ Main.java: 231: προειδοποίηση: [divzero] διαίρεση με μηδενικό μέρισμα επιστροφής / 0; ^ 

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

-Xlint: κενό

Ο σκοπός του -Xlint: κενό είναι να ενημερώσετε τον προγραμματιστή ότι "κενό" αν υπό όρους είναι στον κώδικα. Από τις δοκιμές μου, αυτό φαίνεται να ισχύει μόνο για την περίπτωση του κενού μπλοκ "if". Το NetBeans παρέχει "συμβουλές" (αυτές οι κίτρινες υπογραμμισμένες προειδοποιήσεις που σημειώνονται επίσης στο δεξί περιθώριο του προγράμματος επεξεργασίας πηγαίου κώδικα) για διάφορους τύπους κενών δηλώσεων, αλλά -Xlint: κενό φαίνεται να επισημαίνει μόνο τις κενές δηλώσεις "if". Συμπεριλάβαμε τους άλλους που το NetBeans επισημαίνει μαζί με αυτόν -Xlint: κενό σημαίες στο επόμενο δείγμα πηγαίου κώδικα.

/ ** * Αυτή η μέθοδος δείχνει πώς λειτουργεί το javac's -Xlint: κενό. Σημειώστε ότι το javac's * -Xlint: blank θα επισημαίνει μόνο την κενή δήλωση που εμπλέκεται στο μπλοκ "if", * αλλά δεν επισημαίνει τις κενές δηλώσεις που σχετίζονται με το βρόχο do-while, * the loop loop, το for loop ή το if -αλλού. Το NetBeans επισημαίνει αυτά εάν * είναι ενεργοποιημένες οι κατάλληλες "Συμβουλές". * / private static void demonstrEmptyWarning () {int [] integers = {1, 2, 3, 4, 5}; αν (integers.length! = 5); out.println ("Όχι πέντε;"); if (integers.length == 5) out.println ("Πέντε!"); αλλού; out.println ("Όχι πέντε!"); κάνω; ενώ (integers.length> 0); για (int integer: integers); out.println ("Βρέθηκε άλλος ακέραιος αριθμός!"); int μετρητής = 0; ενώ (μετρητής <5); out.println ("Extra ερωτηματικά.") ;;;; } 

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

src \ dustin \ example \ Main.java: 197: προειδοποίηση: [άδεια] κενή δήλωση μετά εάν εάν (integers.length! = 5); ^ 

Επισημαίνεται μόνο η κενή ρήτρα δήλωσης "if". οι άλλοι δεν αναφέρονται από -Xlint: κενό.

-Xlint: πρωτοποριακή

Μια δελεαστική αλλά αμφιλεγόμενη ευκολία που παρέχει η Java είναι η ικανότητα να "πέφτει" κοινές εκφράσεις σε ένα διακόπτης δήλωση για την εφαρμογή της ίδιας λογικής σε πολλές ακέραιες τιμές με ένα κομμάτι κώδικα. Εάν όλες οι ενσωματωμένες τιμές με την κοινόχρηστη λειτουργικότητα είναι κενές, εκτός από την τελική που εκτελεί πραγματικά τη λειτουργικότητα και παρέχει ένα Διακοπή, ο -Xlint: πρωτοποριακή δεν θα ενεργοποιηθεί. Ωστόσο, εάν μερικά από τα υπόθεση οι εκφράσεις εκτελούν τη δική τους λογική, εκτός από την κοινή λογική, αυτή η προειδοποίηση παράγεται. Παραδείγματα που αποδεικνύουν αυτό φαίνονται στη συνέχεια.

/ ** * Αιτία -Xlint: εναλλακτική εκτύπωση προειδοποίησης σχετικά με τη χρήση του διακόπτη / θήκη * fallthrough. * / ιδιωτικό στατικό κενό δείχνουνFallthroughWarning () {out.print ("Το αγαπημένο χρώμα του Wilma είναι"); out.print (wilma.getFavoriteColor () + ", που είναι"); // ελέγξτε για να δείτε αν το «καλλιτεχνικό» πρωτεύον χρώμα // ΣΗΜΕΙΩΣΗ: Αυτό δεν θα οδηγήσει σε -Xlint: fallthrough επισημαίνοντας μια προειδοποίηση // επειδή δεν περιλαμβάνεται καμία λειτουργικότητα σε καμία από τις δηλώσεις περιπτώσεων // που δεν έχουν δικές τους Διακοπή. διακόπτης (wilma.getFavoriteColor ()) {case BLUE: case ΚΙΤΡΙΝΟ: case RED: out.print ("ένα βασικό χρώμα για καλλιτεχνικές προσπάθειες"); Διακοπή; θήκη ΜΑΥΡΟ: θήκη ΚΑΦΕ: θήκη CORAL: case EGGSHELL: case GREEN: case MAUVE: case ORANGE: case PINK: case PURPLE: case TAN: case WHITE: default: out.print ("NOT a primer artistic color"); } out.print ("και είναι"); // ελέγξτε για να δείτε αν το κύριο χρώμα «πρόσθετο» // ΣΗΜΕΙΩΣΗ: Αυτός ο διακόπτης θα οδηγήσει σε -Xlint: fallthrough που εκπέμπει μια προειδοποίηση // επειδή υπάρχει κάποια λειτουργικότητα σε περίπτωση // έκφραση που δεν έχει τη δική της δήλωση διακοπής . διακόπτης (wilma.getFavoriteColor ()) {case BLUE: case GREEN: out.println ("(δεν είναι εύκολο να είναι πράσινο!)"); υπόθεση RED: out.println ("ένα κύριο χρώμα για πρόσθετες προσπάθειες."); Διακοπή; θήκη ΜΑΥΡΟ: θήκη ΚΑΦΕ: θήκη CORAL: case EGGSHELL: case MAUVE: case ORANGE: case PINK: case PURPLE: case TAN: case ΚΙΤΡΙΝΟ: case WHITE: default: out.println ("NOT a primitive additive color."); }} 

Το παραπάνω παράδειγμα κώδικα εμφανίζει εσκεμμένα και τις δύο περιπτώσεις (προορίζονται για το) του διακόπτη / θήκης που θα οδηγήσουν και δεν θα οδηγήσουν σε προειδοποιητικό μήνυμα χάρη στο -Xlint: πρωτοποριακή. Η έξοδος, με μία μόνο προειδοποίηση, εμφανίζεται στη συνέχεια.

src \ dustin \ example \ Main.java: 95: προειδοποίηση: [πτώση] πιθανή εναλλακτική περίπτωση σε περίπτωση ΚΟΚΚΙΝΟ: ^ 

ο υπόθεση που επισημάνθηκε ήταν το ΚΟΚΚΙΝΟ υπόθεση ακολουθώντας το ΠΡΑΣΙΝΟ υπόθεση που έκανε κάποια δική του λογική πριν περάσει στη λογική RED.

-Xlint: τελικά

Περισσότερα από ένα άτομα έχουν προειδοποιήσει, "Μην επιστρέψετε σε μια ρήτρα επιτέλους." Στην πραγματικότητα, η «επιστροφή της Java δεν είναι πάντα» βρίσκεται στο The Java Hall of Shame. Ένας προγραμματιστής Java μπορεί να ειδοποιηθεί για αυτήν την άθλια κατάσταση χρησιμοποιώντας - Xlint, -Xlint: όλα, ή -Xlint: τελικά. Στη συνέχεια εμφανίζεται ένα κομμάτι πηγαίου κώδικα που δείχνει πώς θα μπορούσε να δημιουργηθεί αυτή η προειδοποίηση.

/ ** * Επίδειξη -Xlint: τελικά δημιουργία προειδοποιητικού μηνύματος όταν ένα μπλοκ {@code τελικά} * δεν μπορεί να τελειώσει κανονικά. * / private static void demonstrFinallyWarning () {try {final double quotient = divideIntegersForDoubleQuotient (10, 0); out.println ("Το πηλίκο είναι" + πηλίκο); } catch (RuntimeException uncheckedException) {out.println ("Έπιασε την εξαίρεση:" + uncheckedException.toString ()); }} / ** * Χωρίστε τον παρεχόμενο διαιρέτη στο παρεχόμενο μέρισμα και επιστρέψτε το * προκύπτον πηλίκο. Δεν γίνονται έλεγχοι για να διασφαλιστεί ότι ο διαιρέτης δεν είναι μηδενικός. * * @param dividend Integer για διαίρεση. * @param divisor Integer με τον οποίο θα διαιρεθεί το μέρισμα. * @return Ποσοστό κατανομής μερίσματος από διαιρέτη. * / private static double divideIntegersForDoubleQuotient (τελικό int μέρισμα, final int divisor) {double quotient = 0,0; δοκιμάστε {if (divisor == 0) {ρίξτε νέο ArithmeticException ("Δεν επιτρέπεται η διαίρεση με μηδέν: δεν μπορεί να εκτελέσει" + μέρισμα + "/" + διαιρέτης); } // Αυτό δεν θα οδηγούσε σε προειδοποίηση Xlint: divzero αν φτάναμε εδώ // με έναν κυριολεκτικό μηδενικό διαιρέτη, διότι το Infinity θα είχε απλώς // επιστραφεί αντί για σιωπηρή ρίψη του ArithmeticException. πηλίκο = (διπλό) μέρισμα / διαιρέτης · } επιτέλους {return quotient }} 

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

src \ dustin \ example \ Main.java: 159: προειδοποίηση: [τελικά] η ρήτρα δεν μπορεί να ολοκληρωθεί κανονικά} ^ 

-Xlint: αντικαθιστά