Πληκτρολογήστε casting java. Μετατροπή πρωτόγονων τύπων σε Java

Πρόγραμμα Kerish Doctor. 15.06.2019
Επισκόπηση προγράμματος Η έκδοση υπολογιστή του Microsoft Excel Viewer θα επιτρέψει...

Chercher

Τύπος χύτευση V αριθμητικές εκφράσειςεκτελείται αυτόματα.

byte->short->int->long->float->double

Εάν οι τελεστές a και b συνδυάζονται από έναν δυαδικό τελεστή (θα το συζητήσουμε παρακάτω), πριν από την εκτέλεση του δυαδικού τελεστή, και οι δύο τελεστές μετατρέπονται στον ίδιο τύπο δεδομένων ως εξής:

  • Εάν ένας από τους τελεστές είναι τύπου double, ο δεύτερος μετατρέπεται επίσης σε διπλό.
  • Εάν ένας από τους τελεστές είναι τύπου float, ο δεύτερος μετατρέπεται επίσης σε float.
  • Εάν ένας από τους τελεστές είναι τύπου long, ο δεύτερος μετατρέπεται επίσης σε long.
  • Εάν ένας από τους τελεστές είναι τύπου int, ο δεύτερος μετατρέπεται επίσης σε int.

Επιτρεπόμενες μετατροπές τύπων

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

Για να περιοριστούν οι κάστες, πρέπει να γίνει σαφές. Για παράδειγμα: byte b = (byte)128; cast int σε byte τύπου.

Προτείνω να κάνουμε μερικά παραδείγματα.

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

  • Τα ονόματα των μεταβλητών δεν μπορούν να ξεκινούν με έναν αριθμό, δεν μπορούν να χρησιμοποιήσουν αριθμητική ή σύμβολα στα ονόματά τους. λογικούς τελεστές, καθώς και το σύμβολο '#'.
  • Η χρήση των χαρακτήρων '$' ή '_' είναι αποδεκτή, συμπεριλαμβανομένης της πρώτης θέσης και του ονόματος.
  • Μια μεταβλητή αρχέγονου τύπου που δηλώνεται ως μέλος κλάσης (καθολική μεταβλητή) ορίζεται στο μηδέν από προεπιλογή.
  • Εάν μια μεταβλητή δηλωθεί ως τοπική μεταβλητή σε μια μέθοδο, πρέπει να αρχικοποιηθεί πριν από τη χρήση. Επειδή οι τοπικές μεταβλητές δεν αρχικοποιούνται από προεπιλογή. Αυτό σημαίνει ότι δεν μπορείτε να δηλώσετε μια τοπική μεταβλητή και να την αφήσετε χωρίς αρχικοποίηση. Δηλαδή, κάπως έτσι: int i;. Εάν το κάνετε αυτό σε μια μέθοδο, ο μεταγλωττιστής θα σας ζητήσει να ορίσετε μια προεπιλεγμένη τιμή, ενώ όταν δημιουργείτε μια τέτοια μεταβλητή ως μέλος κλάσης (καθολική), ο ίδιος ο μεταγλωττιστής θα την ορίσει στο 0.
  • Το εύρος και η διάρκεια ζωής μιας μεταβλητής περιορίζεται από το μπλοκ () στο οποίο δηλώνεται. Εάν δημιουργήσατε μια μεταβλητή μέσα σε μια μέθοδο (όπως κάναμε στα παραδείγματα), τότε δεν μπορείτε να τη χρησιμοποιήσετε εκτός της μεθόδου, καθώς η μέθοδος οριοθετείται με παρενθέσεις (). Η καθολική μεταβλητή είναι ορατή σε όλα τα μπλοκ.
  • Απαγορεύεται επίσης η χρήση λέξεων που προορίζονται για java. Πλήρης λίστα λέξεις-κλειδιάφαίνεται στην παρακάτω εικόνα.

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

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

Υπάρχουν πολλές έξυπνες λέξεις, αλλά αυτή η εικόνα εξηγεί τα πάντα πολύ απλά:

Αρχικά θα χρησιμοποιήσουμε τελεστές σύγκρισης bitwise, ανάθεσης και postfix. Άλλοι τελεστές δεν είναι τόσο συνηθισμένοι, επομένως θα εξετάσουμε μόνο αυτούς που θα χρησιμοποιήσουμε.

    δημόσιας κλάσης OperatorsInJava (

    int a = 5 ;

    int b = 6 ;

    int sum = a + b;

    int διαφορά = a - b;

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

Στην Java, είναι δυνατές οι μετατροπές μεταξύ ακέραιων και τιμών κινητής υποδιαστολής. Επιπλέον, μπορείτε να μετατρέψετε ακέραιες τιμές και τιμές κινητής υποδιαστολής σε τιμές χαρακτήρες και αντίστροφα, καθώς κάθε χαρακτήρας αντιστοιχεί σε ένα ψηφίο στο Κωδικοποίηση Unicode. Στην πραγματικότητα, ο boolean τύπος είναι ο μόνος πρωτόγονος τύπος στην Java που δεν μπορεί να μετατραπεί σε άλλο πρωτόγονο τύπο. Επιπλέον, οποιοσδήποτε άλλος πρωτόγονος τύπος δεν μπορεί να μετατραπεί σε boolean.

Υπάρχουν δύο τύποι μετατροπής τύπων στην Java: υπονοούμενοςΚαι σαφής.

Μετατροπή σιωπηρού τύπουεκτελείται εάν πληρούνται οι ακόλουθες προϋποθέσεις:

  1. Και οι δύο τύποι είναι συμβατοί
  2. Το μήκος του τύπου στόχου είναι μεγαλύτερο ή ίσο με το μήκος του τύπου πηγής

Σε όλες τις άλλες περιπτώσεις θα πρέπει να χρησιμοποιείται μετατροπή ρητού τύπου.

Υπάρχουν επίσης δύο τύποι μετασχηματισμών:

  1. Διεύρυνση μετατροπής
  2. Περιοριστική μετατροπή

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

Αλλά αυτό μπορεί να έχει τις δικές του μικρές τσουγκράνες. Για παράδειγμα, εάν μια τιμή int μετατραπεί σε τιμή float. Και τιμές intσε δυαδική σημείωση μεγαλύτερη από 23 σημαντικά κομμάτια, τότε είναι δυνατή η απώλεια ακρίβειας, καθώς ο τύπος float έχει 23 bit που έχουν εκχωρηθεί για το ακέραιο τμήμα. Όλα τα χαμηλά bitsΟι τιμές int που δεν χωρούν στα 23 bit του float mantissa θα απορριφθούν, οπότε παρόλο που η σειρά του αριθμού θα διατηρηθεί, η ακρίβεια θα χαθεί. Το ίδιο ισχύει και για τη μετατροπή ενός μακρού τύπου σε διπλό.

Η επέκταση της μετατροπής τύπων Java μπορεί επίσης να απεικονιστεί ως εξής:

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

Αξίζει να εξηγήσουμε λίγο γιατί, για παράδειγμα, ο τύπος byte δεν μετατρέπεται αυτόματα (όχι ρητά) στον τύπο char, αν και ο τύπος byte έχει πλάτος 8 bit και ο χαρακτήρας είναι 16, το ίδιο ισχύει και για τη μετατροπή του ο σύντομος τύπος να χαρακ. Αυτό συμβαίνει επειδή το byte και το short είναι υπογεγραμμένοι τύποι δεδομένων και ο χαρακτήρας δεν είναι υπογεγραμμένος. Επομένως, σε σε αυτή την περίπτωσηΠρέπει να χρησιμοποιήσετε casting ρητού τύπου επειδή πρέπει να πείτε ρητά στον μεταγλωττιστή ότι γνωρίζετε τι θέλετε και πώς θα χειριστείτε το bit πρόσημου των byte και των short τύπων κατά τη μετατροπή σε char.

Η συμπεριφορά μιας τιμής char είναι στις περισσότερες περιπτώσεις η ίδια με τη συμπεριφορά μιας τιμής ακέραιου τύπου, επομένως, μια τιμή char μπορεί να χρησιμοποιηθεί όπου απαιτείται μια τιμή int ή long. Ωστόσο, θυμηθείτε ότι ο τύπος χαρακτήρων είναι ανυπόγραφος, επομένως συμπεριφέρεται διαφορετικά από τον σύντομο τύπο, παρόλο που και οι δύο τύποι έχουν εύρος 16 bit.

μικρός μικρό = ( μικρός ) 0xffff; // Αυτά τα bit αντιπροσωπεύουν τον αριθμό -1
απανθρακώνω ντο = "\uffff"; // Τα ίδια bit αντιπροσωπεύουν τον χαρακτήρα unicode
ενθ i1 = μικρό; // Η μετατροπή του short σε int δίνει –1
ενθ i2 = ντο; // Η μετατροπή char σε int δίνει 65535

Στενικός μετασχηματισμός ( περιοριστική μετατροπή) εμφανίζεται όταν μια τιμή μετατρέπεται σε μια τιμή ενός τύπου του οποίου το εύρος δεν είναι μεγαλύτερο από το αρχικό. Ο περιορισμός των μετατροπών δεν είναι πάντα ασφαλής: για παράδειγμα, η μετατροπή της ακέραιας τιμής 13 σε ένα byte είναι λογική, αλλά η μετατροπή του 13000 σε ένα byte είναι άσκοπη, επειδή το byte μπορεί να αποθηκεύσει μόνο τους αριθμούς −128 έως 127. Επειδή ενδέχεται να χαθούν δεδομένα κατά τη διάρκεια μιας περιορισμένης μετατροπής , ο μεταγλωττιστής Java αντιτίθεται σε οποιαδήποτε τέτοια μετατροπή, ακόμα κι αν η τιμή που μετατρέπεται εμπίπτει σε ένα στενότερο εύρος του καθορισμένου τύπου:

ενθ εγώ = 13 ;
ψηφιόλεξη σι = εγώ ; // Ο μεταγλωττιστής δεν θα επιτρέψει αυτήν την έκφραση

Η μόνη εξαίρεση στον κανόνα είναι όταν εκχωρείτε ένα ολόκληρο literal (μια τιμή int) σε ένα byte ή μια σύντομη μεταβλητή εάν το literal ταιριάζει με το εύρος της μεταβλητής.

Μια περιοριστική μετατροπή είναι πάντα μια μετατροπή σαφούς τύπου.

Ρητή μετατροπή πρωτόγονων τύπων

Ο χειριστής της μετατροπής ρητού τύπου, ή πιο συγκεκριμένα, του τύπου χύτευσης, είναι η χρήση παρενθέσεων, μέσα στις οποίες υποδεικνύεται ο τύπος στον οποίο πραγματοποιείται η μετατροπή - (τύπος). Για παράδειγμα:

ενθ εγώ = 13 ;
ψηφιόλεξη σι = ( ψηφιόλεξη ) εγώ ; // Αναγκαστική μετατροπή από int σε byte
εγώ = ( ενθ ) 13.456 ; // Αναγκαστική μετατροπή του διπλού κυριολεκτικού σε int 13

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

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

Πολύ μεγάλο κλασματικός αριθμόςόταν μεταδίδεται σε έναν ακέραιο γίνεται MAX_VALUE ή MIN_VALUE.

Πολύ μεγάλο διπλόόταν φέρεται σε φλοτέρμετατρέπεται σε Float.POSITIVE_INFINITY ή Float.NEGATIVE_INFINITY.

Ο παρακάτω πίνακας είναι ένα πλέγμα όπου, για κάθε πρωτόγονο τύπο, υποδεικνύονται οι τύποι στους οποίους μπορούν να μετατραπούν και πώς μπορούν να μετατραπούν. Επιστολή Νστον πίνακα σημαίνει ότι η μετατροπή δεν είναι δυνατή. Επιστολή Υσημαίνει έναν επεκτεινόμενο μετασχηματισμό που εκτελείται αυτόματα. Επιστολή ΜΕσημαίνει έναν περιορισμένο μετασχηματισμό που απαιτεί ένα ρητό καστ. Τελικά, Υ*σημαίνει έναν αυτόματο μετασχηματισμό διεύρυνσης, κατά τον οποίο η τιμή μπορεί να χάσει μερικά από τα λιγότερο σημαντικά ψηφία της. Αυτό μπορεί να συμβεί κατά τη μετατροπή ενός int ή long σε float ή double. Οι τύποι κινητής υποδιαστολής έχουν μεγαλύτερο εύρος από τους ακέραιους τύπους, επομένως το int ή το long μπορεί να αντιπροσωπεύεται με float ή double. Ωστόσο, οι τύποι κινητής υποδιαστολής είναι προσεγγίσεις αριθμών και μπορεί να μην περιέχουν πάντα τόσα σημαντικά ψηφία στη μάντισσα όσο ακέραιους τύπους.

Αυτόματη επέκταση τύπου σε εκφράσεις

Αξίζει επίσης να αναφερθεί για άλλη μια φορά για την αυτόματη προώθηση (επέκταση) τύπων σε εκφράσεις. Το έχουμε ήδη αντιμετωπίσει αυτό όταν εξετάσαμε τους τύπους δεδομένων ακεραίων και τις λειτουργίες σε αυτούς, αλλά αξίζει να το θυμηθούμε εδώ για να γίνει ακόμα καλύτερα κατανοητό και, επιπλέον, να σχετίζεται άμεσα με αυτό το θέμα. Στο παράδειγμα κάτω από το σημάδι @ + , , * , / και τα λοιπά.

Δηλαδή όλα τα ακέραια κυριολεκτικά σε εκφράσεις, καθώς και τύπους ψηφιόλεξη, μικρόςΚαι απανθρακώνωεπέκταση σε ενθ . Εκτός εάν, όπως περιγράφεται παραπάνω, υπάρχουν άλλοι, μεγαλύτεροι τύποι δεδομένων στην έκφραση ( μακρύς, φλοτέρή διπλό). Επομένως το παραπάνω παράδειγμα θα προκαλέσει σφάλμα μεταγλώττισης επειδή η μεταβλητή ντοέχει τύπο ψηφιόλεξη, και η έκφραση b+1, ως αποτέλεσμα αυτόματη προώθησηέχει τύπο ενθ.

Μετάδοση σιωπηρού τύπου σε κοινές εκφράσεις ανάθεσης

Αν και αυτή η ενότητα σχετίζεται με σιωπηρή μετατροπή τύπων, έχουμε δώσει μια εξήγηση εδώ, καθώς σε αυτήν την περίπτωση λειτουργεί με τον ίδιο τρόπο. αυτόματη επέκτασητύπους σε εκφράσεις και, στη συνέχεια, χύτευση σιωπηρού τύπου. Αυτό είναι το σώμα του μπαλέτου. Νομίζω ότι το παρακάτω παράδειγμα θα ξεκαθαρίσει τα πάντα. Όπως και στην προηγούμενη εξήγηση, το σημάδι @ σημαίνει οποιονδήποτε έγκυρο χειριστή, για παράδειγμα + , , * , / και τα λοιπά.

Αυτό αξίζει να εξηγηθεί με ένα απλό παράδειγμα:

ψηφιόλεξη β2 = 50 ;
β2 = β2 * 2 ; // δεν θα μεταγλωττιστεί
β2 *= 2 ; //μεταγλωττίζει, αν και ισοδυναμεί με b2 = b2 * 2

Η δεύτερη γραμμή που δίνεται στο παράδειγμα δεν μεταγλωττίζεται λόγω αυτόματης επέκτασης τύπου στις εκφράσεις, αφού η έκφραση b2*2 είναι τύπου int, αφού συμβαίνει αυτόματη επέκταση τύπου (τα ακέραια γράμματα στην έκφραση είναι πάντα int). Η τρίτη γραμμή θα μεταγλωττιστεί εύκολα, αφού το σιωπηρό casting στη συνδυασμένη έκφραση ανάθεσης θα λειτουργήσει σε αυτήν.

Boxing/unboxing - μετατροπή πρωτόγονων τύπων σε αντικείμενα περιτυλίγματος

Η πυγμαχία και το unboxing είναι επίσης ένα αρκετά μεγάλο θέμα, αλλά είναι αρκετά απλό.

Ουσιαστικά Το boxing και το unboxing είναι μετατροπές από πρωτόγονους τύπους σε αντικείμενα περιτυλίγματος και πίσω.

Για αντικείμενα περιτυλίγματος πρωτόγονων τύπων ισχύουν όλα όσα ειπώθηκαν παραπάνω.

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

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

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

Επιτρέψτε μου να σας δώσω ένα απλό παράδειγμα:

ενθ i3 ;
ψηφιόλεξη β2 = 3 ;
Ψηφιόλεξη myB ;
myB= β2;
myB++;
β2= myB;
i3= myB;

Εάν δεν είναι ακόμη σαφές γιατί χρειάζεται, τότε δεν είναι τρομακτικό, απλώς δέστε έναν κόμπο ως αναμνηστικό.

Τελευταία ενημέρωση: 29/10/2018

Κάθε βασικός τύποςδεδομένα καταλαμβάνουν ένα ορισμένο ποσό byte μνήμης. Αυτό θέτει έναν περιορισμό στις λειτουργίες που περιλαμβάνουν διάφορα είδηδεδομένα. Εξετάστε το ακόλουθο παράδειγμα:

Int a = 4; byte b = a; // ! Σφάλμα

Σε αυτόν τον κωδικό θα συναντήσουμε ένα σφάλμα. Αν και τόσο ο τύπος byte όσο και ο τύπος int αντιπροσωπεύουν ακέραιους αριθμούς. Επιπλέον, η τιμή της μεταβλητής a, η οποία εκχωρείται σε μια μεταβλητή τύπου byte, εμπίπτει καλά στο εύρος τιμών για byte τύπου (από -128 έως 127). Ωστόσο, συναντάμε ένα σφάλμα στο στάδιο της μεταγλώττισης. Επειδή σε αυτή την περίπτωση προσπαθούμε να εκχωρήσουμε κάποια δεδομένα που χρειάζονται 4 byte σε μια μεταβλητή που θα πάρει μόνο ένα byte.

Ωστόσο, το πρόγραμμα μπορεί να απαιτεί να πραγματοποιηθεί μια τέτοια μετατροπή. Σε αυτήν την περίπτωση, πρέπει να χρησιμοποιήσω τη λειτουργία μετατροπής τύπου (()):

Int a = 4; byte b = (byte)a; // μετατροπή τύπου: από τύπο int σε τύπο byte System.out.println(b); // 4

Η λειτουργία μετατροπής τύπου περιλαμβάνει τον καθορισμό σε παρένθεση του τύπου στον οποίο πρέπει να μετατραπεί η τιμή. Για παράδειγμα, στην περίπτωση της λειτουργίας (byte)a, τα δεδομένα του τύπου int μετατρέπονται στον τύπο byte. Ως αποτέλεσμα, θα λάβουμε μια τιμή τύπου byte.

Ρητές και σιωπηρές μετατροπές

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

Αυτόματες μετατροπές

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

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

Byte b = 7; int d = b; // μετατροπή από byte σε int

Σε αυτήν την περίπτωση, μια τιμή τύπου byte, που καταλαμβάνει 1 byte στη μνήμη, επεκτείνεται στον τύπο int, που καταλαμβάνει 4 byte.

Οι επεκτεινόμενοι αυτόματοι μετασχηματισμοί αντιπροσωπεύονται από τις ακόλουθες αλυσίδες:

byte -> short -> int -> long

int -> διπλός

κοντό -> float -> διπλό

χαρ -> ενθ

Αυτόματες μετατροπές με απώλεια ακρίβειας

Ορισμένες μετατροπές μπορούν να πραγματοποιηθούν αυτόματα μεταξύ τύπων δεδομένων του ίδιου πλάτους bit ή ακόμη και από τύπο δεδομένων με μεγαλύτερο πλάτος bit σε τύπο με μικρότερο πλάτος bit. Αυτές είναι οι ακόλουθες αλυσίδες μετατροπών: int -> float, long -> float και long -> double εκτελούνται χωρίς σφάλματα, αλλά κατά τη μετατροπή μπορεί να συναντήσουμε απώλεια πληροφοριών.

Για παράδειγμα:

Int a = 2147483647; float b = a; // από int σε float System.out.println(b); // 2.14748365E9

Σαφείς μετατροπές

Όλες οι άλλες μετατροπές πρωτόγονων τύπων εφαρμόζουν ρητά τη λειτουργία μετατροπής τύπων. Συνήθως πρόκειται για περιοριστικές μετατροπές από έναν τύπο με μεγαλύτερο πλάτος bit σε έναν τύπο με μικρότερο πλάτος bit:

Long a = 4; int b = (int) a;

Απώλεια δεδομένων κατά τη μετατροπή

Όταν χρησιμοποιούμε ρητές μετατροπές, ενδέχεται να αντιμετωπίσουμε απώλεια δεδομένων. Για παράδειγμα, δεν θα έχουμε προβλήματα με τον παρακάτω κώδικα:

Int a = 5; byte b = (byte) a; System.out.println(b); // 5

Ο αριθμός 5 ταιριάζει καλά στο εύρος των τιμών byte, οπότε μετά τη μετατροπή η μεταβλητή b θα είναι ίση με 5. Τι συμβαίνει όμως στην ακόλουθη περίπτωση:

Int a = 258; byte b = (byte) a; System.out.println(b); // 2

Το αποτέλεσμα θα είναι ο αριθμός 2. Σε αυτήν την περίπτωση, ο αριθμός 258 είναι εκτός εύρους για τον τύπο byte (-128 έως 127), επομένως η τιμή θα περικοπεί. Γιατί το αποτέλεσμα θα είναι ο αριθμός 2;

Ο αριθμός α, που είναι 258, σε δυαδικό σύστημαθα ισούται με 00000000 00000000 00000001 00000010 . Οι τιμές byte καταλαμβάνουν μόνο 8 bit μνήμης. Επομένως, η δυαδική αναπαράσταση ενός int περικόπτεται στα δεξιά 8 ψηφία, δηλαδή 00000010, που σε δεκαδικό σύστημα δίνει τον αριθμό 2.

Περικοπή ρητών αριθμών σε ακέραιους αριθμούς

Κατά τη μετατροπή τιμών κινητής υποδιαστολής σε ακέραιες, το κλασματικό τμήμα περικόπτεται:

Διπλό a = 56,9898; int b = (int)a;

Εδώ η τιμή του b θα ήταν 56, παρόλο που το 57 θα ήταν πιο κοντά στο 56,9898. Για να αποφύγετε τέτοια περιστατικά, πρέπει να χρησιμοποιήσετε τη λειτουργία στρογγυλοποίησης, η οποία είναι διαθέσιμη στο μαθηματική βιβλιοθήκηΙάβα:

Διπλό a = 56,9898; int b = (int)Math.round(a);

Μετασχηματισμοί κατά τη διάρκεια εργασιών

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

    αν ένας από τους τελεστές της πράξης είναι τύπου double, τότε ο δεύτερος τελεστής μετατρέπεται σε τύπου double

    αν δεν πληρούται η προηγούμενη συνθήκη και ένας από τους τελεστές της πράξης είναι τύπου float, τότε ο δεύτερος τελεστής μετατρέπεται σε τύπου float

    αν δεν πληρούνται οι προηγούμενες προϋποθέσεις, ένας από τους τελεστές της πράξης είναι τύπου long, τότε ο δεύτερος τελεστής μετατρέπεται σε type long

    διαφορετικά όλοι οι τελεστές της πράξης μετατρέπονται σε τύπο int

Παραδείγματα μετασχηματισμών:

Int a = 3; διπλό b = 4,6; διπλό c = a+b;

Εφόσον η πράξη περιλαμβάνει διπλή τιμή, τόσο η άλλη τιμή μετατρέπεται στον διπλό τύπο και το άθροισμα των δύο τιμών a+b ​​θα αντιπροσωπεύει τον διπλό τύπο.

Άλλο παράδειγμα:

Byte a = 3; σύντομο b = 4; byte c = (byte)(a+b);

Οι δύο μεταβλητές είναι τύπου byte και short (όχι double, float ή long), οπότε όταν προστεθούν μετατρέπονται σε τύπο int και το άθροισμά τους a+b αντιπροσωπεύει μια τιμή int. Επομένως, εάν στη συνέχεια αντιστοιχίσουμε αυτό το ποσό σε μια μεταβλητή τύπου byte, τότε πρέπει και πάλι να κάνουμε μια μετατροπή τύπου σε byte.

Εάν οι λειτουργίες περιλαμβάνουν δεδομένα τύπου char, τότε μετατρέπονται σε int:

Int d = "a" + 5; System.out.println(d); // 102

1. Τι είναι ρητή και αυτόματη χύτευση σε εκφράσεις;

Η χύτευση τύπου μπορεί να είναι ρητή ή αυτόματη.

Με τη χύτευση ρητού τύπου, η ίδια η λειτουργία χύτευσης προσδιορίζεται ρητά.

Κατά την εκτέλεση αυτόματης χύτευσης τύπου, πρέπει να πληρούνται δύο προϋποθέσεις:

  • Και οι δύο τύποι πρέπει να είναι συμβατοί.
  • το μήκος του τύπου πηγής (τύπος πηγής) πρέπει να είναι μικρότερο από το μήκος του τύπου προορισμού (τύπος νεροχύτη).

2. Πώς φαίνεται η χύτευση ρητού τύπου στις εκφράσεις; Παραδείγματα

Η χύτευση ρητού τύπου επιτρέπει την αντιστοίχιση μη συμβατών τύπων. Γενική μορφήΈνα καστ ρητού τύπου μοιάζει με αυτό:

τιμή (τύπος_στόχου).

target_type– αυτός είναι ο τύπος στον οποίο θέλετε να μεταδώσετε το καθορισμένο έννοια.

Παραδείγματαχύτευση ρητού τύπου.

// χύτευση ρητού τύπου σε εκφράσεις byte b; int a? διπλό d? float f; d = -39,9203; a = (int )d; // a = -39 f = (float )d; // f = -39,9203 b = (byte )d; // b = -39 d = 302930932; b = (byte )d; // b = -12 - περικοπή της τιμής a = -27; b = (byte)a; // b = -27

3. Παραδείγματα αυτόματου τύπου χύτευσης

Παράδειγμα 1. Αυτόματη χύτευση ακέραιων τύπων.

// αυτόματη χύτευση ακέραιων τύπων int a? byte b; κοντό sh? b = -23; a = b; // a = -23 - αυτόματη χύτευση τύπου sh = -150; a = sh; // a = -150 μήκος l = 200; // Σφάλμα: "Αναντιστοιχία τύπου: δεν μπορεί να μετατραπεί από long σε int" // a = l; l = b; // l = -23 l = sh; // l = -150 char c = "Z" ; a = c; // a = 90 - κωδικός χαρακτήρων "Z" boolean b1 = false ; //a = b1; - σφάλμα, οι τύποι δεν είναι συμβατοί

Παράδειγμα 2. Αυτόματη χύτευση τύπων κινητής υποδιαστολής.

// αυτόματη χύτευση τύπων κινητής υποδιαστολής float f; διπλό d? f = 3,409033f; d = f; // d = 3,409033

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

// αυτόματη χύτευση μικτών τύπων float f; διπλό d? a = 28; d = a; // d = 28,0 f = a; // f = 28,0 // Σφάλμα: Ασυμφωνία τύπου: δεν είναι δυνατή η μετατροπή από float σε int // a = f;

4. Πώς γίνεται η αυτόματη προώθηση τύπου σε εκφράσεις;

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

Κατά την αυτόματη προώθηση τύπων σε εκφράσεις:

  • εάν ένας από τους ακέραιους τελεστές είναι τύπου int, τότε όλες οι τιμές τύπου byte, short και char προωθούνται σε τύπο int.
  • Εάν ένας από τους ακέραιους τελεστές είναι τύπου long, τότε ολόκληρη η έκφραση προωθείται σε type long.
  • εάν ένας από τους τελεστές είναι τύπου float, τότε ο τύπος ολόκληρης της παράστασης θα είναι επίσης τύπου float (αν δεν υπάρχουν τελεστές τύπου double).
  • εάν ένας από τους τελεστές είναι τύπου double, τότε και ο τύπος ολόκληρης της παράστασης θα είναι διπλός.

5. Ένα παράδειγμα προώθησης από byte τύπου σε int στο οποίο η έκφραση δεν περιέχει μεταβλητούς τελεστές τύπου int (long)
// byte -> ενθ byte b; b = 1000 / 20; // b = 50, λειτουργεί επειδή το αποτέλεσμα τοποθετείται σε τύπο byte

Το παραπάνω παράδειγμα λειτουργεί σωστά γιατί:

  • το αποτέλεσμα τοποθετείται (συμβατό) στον τύπο byte.
  • δεν υπάρχουν τελεστές τύπου int.

Στο παραπάνω παράδειγμα, η τιμή 1000 υπερβαίνει το εύρος τιμών byte.

1000 / 20 = 50

Αρχικά, ο αριθμός 1000 μεταδίδεται για να πληκτρολογήσει int. Το αποτέλεσμα όμως .

μεταδίδεται σε byte και μπορεί να χωρέσει σωστά σε μια μεταβλητή

byte b; σι Αν το γράψεις έτσι:

b = 100000 / 20;

// σφάλμα επειδή το αποτέλεσμα δεν ταιριάζει στον τύπο byte

100000 / 20 = 5000

τότε θα εμφανιστεί ένα σφάλμα μεταγλώττισης με το μήνυμα:

Σε αυτήν την περίπτωση, το αποτέλεσμα δεν τοποθετείται στον τύπο byte:

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

τότε σε αυτήν την περίπτωση το αποτέλεσμα 5000 τύπου int μετατρέπεται σε byte τύπου.

Όπως γνωρίζετε, μια μεταβλητή τύπου int καταλαμβάνει 32 bit και μια μεταβλητή τύπου byte καταλαμβάνει 8 bit. Η τιμή μιας μεταβλητής int περικόπτεται. Και έχουμε αυτό που έχουμε (b = -120). Τα παραπάνω παραδείγματα ισχύουν και για μεταβλητέςσύντομοι τύποι

και χαρακ.
6. Παράδειγμα. Προώθηση από byte σε int όπου η έκφραση περιέχει έναν τελεστή μεταβλητής int // byte -> ενθ byte b; // προώθηση τύπων σε εκφράσεις int d; d = 20; // σφάλμα, το αποτέλεσμα είναι τύπου int, αφού η μεταβλητή d είναι τύπου int

// b = 1000 / d; Στο παραπάνω παράδειγμα, η έκφραση χρησιμοποιεί μια μεταβλητήρε

πληκτρολογήστε int. Επομένως, ο μεταγλωττιστής θα παράγει ένα μήνυμα σφάλματος:

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

Επειδή η έκφραση χρησιμοποιεί μια μεταβλητή τελεστή

6. Παράδειγμα. Προώθηση από byte σε int όπου η έκφραση περιέχει έναν τελεστή μεταβλητής int // byte -> ενθ byte b; πληκτρολογήστε int. int d; Εάν εκτελέσετε cast ρητού τύπου, το αποτέλεσμα θα είναι σωστό: int d;

b = (byte) (1000/d);

// b = 50 - λειτουργεί σωστά

// προώθηση τύπων σε εκφράσεις 7. Παράδειγμα. Προώθηση από int σε long Ένα παράδειγμα προώθησης τύπου από int σε long. Εάν ένας από τους τελεστές είναι τύπου long, τότε ολόκληρη η έκφραση προωθείται σε type long. longl? d = 10000 * 200; // έργα, d = 2000000 // Σφάλμα! Αναντιστοιχία τύπων: δεν μπορεί να μετατραπεί από long σε int // d = 1L * 2L; - Οι τελεστές 1L και 2L είναι μακρού τύπου

l = 100;

// σφάλμα, ένας από τους τελεστές είναι τύπου long // d = l * 2;Όπως φαίνεται από το παράδειγμα, εάν ένας από τους τελεστές είναι τύπου long , τότε ολόκληρη η έκφραση γίνεται τύπου long . Συχνά υπάρχει ανάγκη μετατροπής συμβολοσειρών σε τιμές άλλων τύπων, όπως int ή boolean, και αντίστροφα. Σύμφωνα με την αποδεκτή σύμβαση, η ευθύνη για τη μετατροπή της χορδής V η τιμή ενός άλλου τύπου εκχωρείται στην αντίστοιχη μέθοδο αυτού του τύπου. Έτσι, για παράδειγμα, η μετατροπή μιας συμβολοσειράς σε τιμή int κάνειστατική μέθοδος

από την κλάση περιτυλίγματος Integer. ΣΕ

παρακάτω πίνακα

Καθορίζονται όλοι οι τύποι που μπορούν να μετατραπούν από τιμές σε συμβολοσειρές και αντίστροφα και παρατίθενται οι αντίστοιχες μέθοδοι.

TYPE Μέθοδος μετατροπής - Μέθοδος μετατροπής από συμβολοσειρά

tion To line

boolean String.valueOf(boolean) new.Boolean(String). booleanvalue()

byte String.valueOf(byte) Byte.parseByte(string, int)

short String.valueOf(short) Short.parseShort(string, int)

double String.valueOf(double) Double.parseDouble(String)

Για να μετατρέψετε μια συμβολοσειρά σε τιμή Boole, πρέπει να δημιουργήσετε ένα αντικείμενο Boole και στη συνέχεια να υποβάλετε ερώτημα για την τιμή του. Όλες οι άλλες κλάσεις περιτυλίγματος περιέχουν τις αντίστοιχες μεθόδους αναλύω λέξη.Μέθοδοι αναλύω λέξηΟι ακέραιοι τύποι υπάρχουν σε δύο υπερφορτωμένες μορφές: η πρώτη, εκτός από τη συμβολοσειρά, απαιτεί τον καθορισμό ενός πρόσθετου ορίσματος τύπου int, που αντιπροσωπεύει τη βάση του συστήματος αριθμών - από 2 έως 32. το δεύτερο παίρνει μόνο μια παράμετρο συμβολοσειράς και από προεπιλογή προϋποθέτει τη χρήση μετρικό σύστημαΥπολογισμός. Σε όλες τις περιπτώσεις εκτός από το Boolean, γίνεται η ακόλουθη υπόθεση: Εάν η συμβολοσειρά αντιπροσωπεύει μια τιμή που δεν μπορεί να μετατραπεί σωστά σε έναν αριθμό του κατάλληλου τύπου, εμφανίζεται ένα NumberFormatException. Η κλάση Boolean ακολουθεί τη σύμβαση ότι οποιαδήποτε παράμετρος συμβολοσειράς δεν είναι ίση με "true" (χωρίς διάκριση πεζών-κεφαλαίων) έχει ως αποτέλεσμα τη δημιουργία ενός Boolean αντικειμένου με την τιμή false.

Μέθοδοι που σας επιτρέπουν να μετατρέψετε χαρακτήρες που αντιπροσωπεύονται σε μία από τις μορφές που υποστηρίζονται από τη γλώσσα (όπως \b, \uxxxxκ.λπ.), τιμές τύπου char και αντίστροφα δεν υπάρχουν. Να πάρει Αντικείμενο συμβολοσειράςπου περιέχει έναν μόνο χαρακτήρα, απλώς καλέστε τη μέθοδο String.valueOf, μεταβιβάζοντάς της την αντίστοιχη τιμή char ως παράμετρο.

Επίσης, δεν υπάρχουν τρόποι για τη δημιουργία αναπαραστάσεων συμβολοσειρών αριθμών που καθορίζονται σε μία από τις μορφές που υποστηρίζονται από τη γλώσσα - με το μηδέν (O) στην αρχή οκταδικός αριθμός, και το πρόθεμα Οх (ή ΟΧ), που χρησιμεύει ως σημάδι δεκαεξαδικό σύστημαΥπολογισμός. Αντίθετα, οι κλάσεις περιτυλίγματος ακεραίων υποστηρίζουν εκδόσεις της μεθόδου αποκωδικοποίησης που μπορούν να μετατρέψουν συμβολοσειρές σε αριθμητικές τιμές του κατάλληλου τύπου και να κατανοήσουν ότι το αρχικό O είναι οκταδικός αριθμός και ένα από τα προθέματα Ox OR Ox είναι δεκαεξαδικός αριθμός.

Οποιαδήποτε κλάση εφαρμογής μπορεί να παρέχει υποστήριξη για τη μετατροπή των δικών της αντικειμένων σε συμβολοσειρές και αντίστροφα, εάν η δήλωσή της παρακάμπτει τη μέθοδο toString αναλόγως και παρέχει έναν ειδικό κατασκευαστή που δημιουργεί ένα αντικείμενο κλάσης με βάση τη συμβολοσειρά που μεταβιβάζεται ως παράμετρος. Έχετε επίσης τη μέθοδο String.valueOf(Object obj), η οποία επιστρέφει είτε ένα αντικείμενο συμβολοσειράς "null" (αν το obj είναι null) είτε το αποτέλεσμα της μεθόδου obj.toString. Κατηγορία χορδώνπεριέχει επαρκή αριθμό υπερφορτώσεων της μεθόδου valueOf που σας επιτρέπουν να μετατρέψετε οποιαδήποτε τιμή οποιουδήποτε τύπου σε αντικείμενο String χρησιμοποιώντας απλή κλήση valueOf με τη μετάδοση του απαιτούμενου ορίσματος.



Συνιστούμε να διαβάσετε

Κορυφή