java:autoboxing

Autoboxing και Unboxing

Ο compiler της Java μας δίνει την δυνατότητα να χρησιμοποιήσουμε βασικούς τύπους σε σημεία του κώδικα που απαιτείται η ισοδύναμη αναφορική μορφή ή αναφορικούς τύπους σε σημεία του κώδικα που ζητείται η βασική μορφή. Ο compiler έχει την ιδιότητα να αναγνωρίζει σημεία του κώδικα που απαιτούν τις παραπάνω μετατροπές τύπου και κάνει αυτόματα τις μετατροπές αυτές. Θα δώσουμε παρακάτω από ένα παράδειγμα μετατροπής πάνω στο οποίο θα συζητήσουμε τις διαδικασίες Autoboxing και Unboxing.

Autoboxing

AutoboxExample.java
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, μπορεί να γραφεί ως εξής:

AutoboxExample.java
public class AutoboxExample {
  public static void main(String []args) {
    int a=5;
    System.out.println("a: "+ (new Integer(a)).toString() );
  }
}

Οι δύο παραπάνω κλάσεις είναι ισοδύναμες. Η αιτία της ισοδυναμίας είναι η ιδιότητα του compiler να αναγνωρίζει την ανάγκη μετατροπής ενός βασικού τύπου σε αναφορικό.

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

Unboxing

UnboxExample.java
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 είναι ο παρακάτω.

UnboxExample.java
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). Αντ' αυτού λαμβάνουμε το παρακάτω μήνυμα λάθους

UnboxExample.java
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/autoboxing.txt · Last modified: 2017/02/16 12:36 by gthanos