java:generics

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revision Both sides next revision
java:generics [2015/03/15 19:32]
gthanos created
java:generics [2015/03/15 20:20]
gthanos [Παραμετρικοί τύποι δεδομένων με πολλές παραμέτρους]
Line 1: Line 1:
-====== Generics ======+====== ​Παραμετρικοί τύποι δεδομένων (Generics======
  
-Ένας //generic// (γενικός) τύπος δεδομένων είναι ένας τύπος δεδομένων ο οποίος μπορεί να λαμβάνει ως παραμέτρους άλλους τύπους δεδομένων. Δείτε το παρακάτω παράδειγμα.+Ένας //generic// (γενικός) τύπος δεδομένων είναι ένας τύπος δεδομένων ο οποίος μπορεί να λαμβάνει ως παραμέτρους άλλους τύπους δεδομένων. Δείτε το παρακάτω παράδειγμα ​της κλάσης Box, η οποία θέλουμε να μπορεί να αποθηκεύσει οποιονδήποτε τύπο δεδομένων.
  
 <code java Box.java>​ <code java Box.java>​
Line 15: Line 15:
  
 <code java BoxUsage.java>​ <code java BoxUsage.java>​
-public BoxUsage {+public ​class BoxUsage {
    ​public static void main(String args[]) {    ​public static void main(String args[]) {
      Box b = new Box();      Box b = new Box();
      ​Integer n = new Integer(5);      ​Integer n = new Integer(5);
      ​b.set(n);​      ​b.set(n);​
-     ​String s = b.get();+     ​String s = (String)b.get();
    }    }
 } }
 </​code>​ </​code>​
 +
 +Ο παραπάνω κώδικας αφού μεταγλωττιστεί και επιχειρήσουμε να το τρέξουμε παράγει το παρακάτω exception
 +<​code>​
 +Exception in thread "​main"​ java.lang.ClassCastException:​ java.lang.Integer cannot be cast to java.lang.String
 +        at BoxUsage.main(BoxUsage.java:​7)
 +</​code>​
 +
 +Παρατηρήστε επίσης,​ ότι στην τελευταία γραμμή είμαστε υποχρεωμένοι να κάνουμε cast την επιστρεφόμενη τιμή της μεθόδου get() από Object σε String. Προκειμένου να αποφύγουμε τα παραπάνω προβλήματα και να είμαστε σίγουροι ότι ο κώδικας που γράφουμε δεν περιέχει λάθος χρήση τύπων δεδομένων η Java είσαγει τους γενικούς τύπους,​ γνωστούς ως generics. Η κλάση Box με χρήση Generics θα μπορούσε να γραφεί ως εξής:
 +
 +<code java Box.java>​
 +/**
 + * Generic version of the Box class.
 + * @param <T> the type of the value being boxed
 + */
 +public class Box<​T>​ {
 +  // T stands for "​Type"​
 +  private T t;
 +
 +  public void set(T t) { this.t = t; }
 +  public T get() { return t; }
 +}
 +</​code>​
 +
 +===== Ονοματολογία παραμέτρων =====
 +
 +  * E - Element (χρησιμοποείται στο Java Collections Framework)
 +  * K - Key
 +  * N - Number
 +  * T - Type
 +  * V - Value
 +  * S,U,V etc. - 2nd, 3rd, 4th types
 +
 +===== Δημιουργία και χρήση αντικειμένων ενός γενικού τύπου δεδομένων =====
 +
 +<code java>
 +Box<​Integer>​ integerBox = new Box<​Integer>​();​
 +</​code>​
 +
 +Εναλλακτικά μπορείτε να γράψετε
 +<code java>
 +Box<​Integer>​ integerBox = new Box<>​();​
 +</​code>​
 +
 +Εδώ ο compiler αντιλαμβάνεται ότι δημιουργείται μία μεταβλητή τύπου ''​Box<​Integer>''​ και δημιουργεί ένα αντικείμενο αυτού του τύπου
 +
 +**Προσοχή:​** το παραπάνω δεν είναι ίδιο με το παρακάτω. ​
 +<code java>
 +Box<​Integer>​ integerBox = new Box();
 +</​code>​
 +
 +Στο τελευταίο ο compiler θα εκδώσει το παρακάτω warning.
 +<​code>​
 +Note: BoxUsage.java uses unchecked or unsafe operations.
 +Note: Recompile with -Xlint:​unchecked for details.
 +</​code>​
 +
 +===== Παραμετρικοί τύποι δεδομένων με πολλές παραμέτρους =====
 +
 +<code java Pair.java>​
 +public interface Pair<K, V> {
 +    public K getKey();
 +    public V getValue();
 +}
 +</​code>​
 +
 +<code java OrderedPair.java>​
 +public class OrderedPair<​K,​ V> implements Pair<K, V> {
 +
 +    private K key;
 +    private V value;
 +
 +    public OrderedPair(K key, V value) {
 + this.key = key;
 + this.value = value;
 +    }
 +
 +    public K getKey() { return key; }
 +    public V getValue() { return value; }
 +}
 +</​code>​
 +
 +Με βάση τον παραπάνω κώδικα μπορείτε να δημιουργήσετε αντικείμενα επιμέρους τύπων ως εξής:
 +<code java OrderedPairUsage.java>​
 +public class OrderedPairUsage {
 +  public static void main(String args[]) {
 +    Pair<​String,​ Integer> p1 = new OrderedPair<​String,​ Integer>​("​Even",​ 8);
 +    Pair<​String,​ String> ​ p2 = new OrderedPair<​String,​ String>​("​hello",​ "​world"​);​
 +    OrderedPair<​String,​ Box<​Integer>>​ p = new OrderedPair<>​("​primes",​ new Box<​Integer>​());​
 +    // the following is not allowed
 +    Pair<​String,​ Integer> p1 = new OrderedPair<>​("​hello",​ "​world"​);​
 +  }
 +}
 +</​code>​
 +
 +===== Απλοί παραμετρικοί τύποι δεδομένων (Raw Generic Types) =====
 +
 +Εάν δεν χρησιμοποιήσουμε καμία παράμετρο τότε καταλήγουμε να έχουμε έναν "​απλό"​ παραμετρικό τύπο δεδομένων γνωστό ως **Raw types**. Η χρήση των τύπων αυτών δυσκολεύει τον compiler να αποφασίσει για την ασφαλή ή μη χρήση δεδομένων αυτού του τύπου, ειδικά όταν τα δεδομένα αυτά χρησιμοποιούνται μαζί με παραμετρικούς τύπους δεδομένων. Δείτε τα παρακάτω παραδείγματα κώδικα
 +
 +<code java>
 +Box<​String>​ stringBox = new Box<>​();​
 +Box rawBox = stringBox; ​              // Safe - OK
 +</​code>​
 +
 +<code java>
 +Box rawBox = new Box(); ​          // rawBox is a raw type of Box<​T>​
 +Box<​Integer>​ intBox = rawBox; ​    // warning: unchecked conversion
 +</​code>​
 +
 +<code java>
 +Box<​String>​ stringBox = new Box<>​();​
 +Box rawBox = stringBox;
 +rawBox.set(8); ​             // warning: unchecked invocation to set(T)
 +</​code>​
 +
 +==== Unchecked Error Messages ====
 +
 +Όπως είπαμε προηγούμενα η μίξη generics με raw types μπορεί να δημιουργήσει warnings κατά την μεταγλώττιση της μορφής
 +<​code>​
 +Note: Example.java uses unchecked or unsafe operations.
 +Note: Recompile with -Xlint:​unchecked for details.
 +</​code>​
 +όπως παρακάτω
 +<code java WarningDemo.java>​
 +public class WarningDemo {
 +    public static void main(String[] args){
 +        Box<​Integer>​ bi;
 +        bi = createBox();​
 +    }
 +
 +    static Box createBox(){
 +        return new Box();
 +    }
 +}
 +</​code>​
 +Μεταγλωττίζοντας με το flag ''​-Xlint:​unchecked''​ εμφανίζει την παραπάνω χρήση
 +<​code>​
 +WarningDemo.java:​4:​ warning: [unchecked] unchecked conversion
 +found   : Box
 +required: Box<​java.lang.Integer>​
 +        bi = createBox();​
 +                      ^
 +1 warning
 +</​code>​
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
  
  
java/generics.txt · Last modified: 2017/02/17 15:01 by gthanos