====== Auto-boxing και Auto-unboxing ======
Ο compiler της Java μας δίνει την δυνατότητα να χρησιμοποιήσουμε βασικούς τύπους σε σημεία του κώδικα που απαιτείται η ισοδύναμη αναφορική μορφή ή αναφορικούς τύπους σε σημεία του κώδικα που ζητείται η βασική μορφή. Ο compiler έχει την ιδιότητα να αναγνωρίζει σημεία του κώδικα που απαιτούν τις παραπάνω μετατροπές τύπου και κάνει αυτόματα τις μετατροπές αυτές. Η ιδιότητα αυτή του Java compiler απαντάται στην βιβλιογραφεία ως Auto-boxing και Auto-unboxing. Θα δώσουμε παρακάτω από ένα παράδειγμα μετατροπής πάνω στο οποίο θα συζητήσουμε τις διαδικασίες [[https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html|Auto-boxing και Auto-unboxing]].
===== Autoboxing =====
public class AutoboxExample {
public static void main(String []args) {
int a=5;
System.out.println("a: "+a);
}
}
Ο παραπάνω κώδικας εκτυπώνει την τιμή της μεταβλητής //a// που τυγχάνει να είναι βασικού τύπου. Για να το επιτύχει αυτό καλείται να εκτυπώσει ένα αλφαριθμητικό (//String//) που αποτελείται από την ένωση δύο αλφαριθμητικών όπως αυτά ορίζονται πριν και μετά τον τελεστή //+//. Αριστερά του τελεστή //+// έχουμε το αλφαριθμητικό ''"a: "'' ενώ δεξιά του τελεστή έχουμε μία μεταβλητή τύπου int. Προκειμένου να μπορεί να εκτελεστεί το πρόγραμμα, ο compiler θα πρέπει να μετατρέψει τον βασικό τύπο σε αναφορικό και στη συνέχει να καλέσει την συνάρτηση //toString()// του αναφορικού τύπου που επιστρέφει την τιμή της μεταβλητής ως String.
Η παραπάνω αυτόματη μετατροπή που κάνει ο compiler, μπορεί να γραφεί ισοδύναμα ως εξής:
public class AutoboxExample {
public static void main(String []args) {
int a=5;
System.out.println("a: "+ (new Integer(a)).toString() );
}
}
Οι δύο παραπάνω κλάσεις είναι ισοδύναμες. Η αιτία της ισοδυναμίας είναι η ιδιότητα του compiler να αναγνωρίζει την ανάγκη μετατροπής ενός βασικού τύπου σε αναφορικό.
Στο συγκεκριμένο παράδειγμα, ο compiler εκτός από την μετατροπή του τύπου καλεί αυτόματα και την μέθοδο //toString()// προκειμένου να λάβει την τιμή του ακεραίου ως αλφαριθμητικό. Η αυτόματη κλήση της μεθόδου //toString()// αποτελεί μία επιπλέον δυνατότητα του Java compiler.
===== Auto-unboxing =====
public class UnboxExample {
public static int sum(int a, int b) {
return a+b;
}
public static void main(String []args) {
Integer a = new Integer(5);
Integer b = new Integer(10);
int result = sum(a,b);
System.out.println("sum: "+ result );
}
}
Στο παραπάνω παράδειγμα, είναι προφανές ότι η μέθοδος //sum// λαμβάνει ως ορίσματα δύο ακεραίους βασικού τύπου, ενώ τα ορίσματα με τα οποία καλείται η συνάρτηση είναι ακέραιοι αναφορικού τύπου //Integer//. Ο compiler αντιλαμβάνεται ότι προκειμένου να χρησιμοποιηθεί η συνάρτηση απαιτείται η μετατροπή των δύο μεταβλητών αναφορικού τύπου σε βασικού τύπου. Ο ισοδύναμος κώδικας που υλοποιεί ο compiler είναι ο παρακάτω.
public class UnboxExample {
public static int sum(int a, int b) {
return a+b;
}
public static void main(String []args) {
Integer a = new Integer(5);
Integer b = new Integer(10);
int result = sum(a.intValue(),b.intValue());
System.out.println("sum: "+ result );
}
}
Ο compiler έχει την δυνατότητα να μετατρέπει τους βασικούς τύπους σε ισοδύναμους αναφορικούς και αντίστροφα, αλλά δεν επιτρέπει την μετατροπή σε μη ισοδύναμους τύπους. Για παράδειγμα, στο παρακάτω πρόγραμμα, εάν ο ένας από τους δύο αριθμούς είναι τύπου //Long// αντί για //Integer// τότε δεν καλείται η μέθοδος //a.intValue()// (είναι διαθέσιμη και στην κλάση //Long//). Αντ' αυτού λαμβάνουμε το παρακάτω μήνυμα λάθους
public class UnboxExample {
public static int sum(int a, int b) {
return a+b;
}
public static void main(String []args) {
Long a = new Long(5);
Integer b = new Integer(10);
int result = sum(a,b);
System.out.println("sum: "+ result );
}
}
$ javac UnboxExample.java
UnboxExample.java:9: error: method sum in class UnboxExample cannot be applied to given types;
int result = sum(a,b);
^
required: int,int
found: Long,Integer
reason: actual argument Long cannot be converted to int by method invocation conversion
1 error
|Προηγούμενο: [[:java:wrapper_classes | Βασικοί τύποι δεδομένων και ισοδύναμοι αναφορικοί τύποι ]] | [[:toc | Περιεχόμενα]] | Επόμενο: [[:java:packages:intro | Πακέτα ]]|