java:generics
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| java:generics [2017/02/07 14:44] – [Απλοί παραμετρικοί τύποι δεδομένων (Raw Generic Types)] gthanos | java:generics [2020/03/10 09:44] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Παραμετρικοί τύποι δεδομένων (Generics) ====== | ====== Παραμετρικοί τύποι δεδομένων (Generics) ====== | ||
| - | Ένας | + | Ένας |
| - | Δείτε το παρακάτω παράδειγμα της κλάσης Box, η οποία θέλουμε να μπορεί να αποθηκεύσει οποιονδήποτε τύπο δεδομένων. | + | Η υιοθέτηση γενικών κλάσεων έχει το πλεονέκτημα ότι μπορεί να αποθηκεύσει αντικείμενα οποιασδήποτε κλάσης, |
| + | |||
| + | ===== Παράδειγμα γενικής κλάσης για την αποθήκευση δεδομένων ===== | ||
| + | |||
| + | Δείτε το παρακάτω παράδειγμα της κλάσης | ||
| <code java Box.java> | <code java Box.java> | ||
| Line 14: | Line 18: | ||
| </ | </ | ||
| - | Στο παραπάνω παράδειγμα | + | Ας υποθέσουμε ότι έχετε |
| <code java BoxUsage.java> | <code java BoxUsage.java> | ||
| Line 22: | Line 26: | ||
| | | ||
| | | ||
| - | String | + | Integer |
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | Ο παραπάνω | + | Στο |
| - | <code> | + | * να περάσετε |
| - | Exception in thread " | + | * να αναθέσετε την επιστρεφόμενη τιμή της μεθόδου //get// σε οποιοδήποτε τύπο δεδομένων. |
| - | | + | |
| + | Παρατηρήστε ότι στην τελευταία γραμμή είμαστε υποχρεωμένοι να κάνουμε typecast την | ||
| + | |||
| + | Δείτε τώρα το παρακάτω παράδειγμα κώδικα | ||
| + | |||
| + | <code java BoxUsage.java> | ||
| + | public class BoxUsage | ||
| + | | ||
| + | Box b = new Box(); | ||
| + | | ||
| + | b.set(n); | ||
| + | | ||
| + | } | ||
| + | } | ||
| </ | </ | ||
| - | Παρατηρήστε επίσης, ότι | + | Η μετατροπή τύπου στην τελευταία γραμμή είναι προφανώς λάθος, διότι επιχειρούμε να αναθέσουμε |
| + | |||
| + | ===== Παράδειγμα παραμετρικής κλάσης ===== | ||
| + | |||
| + | Προκειμένου να αποφύγουμε τα παραπάνω προβλήματα και να είμαστε σίγουροι ότι ο κώδικας που γράφουμε δεν περιέχει λάθη στη χρήση τύπων δεδομένων η Java εισάγει τους παραμετρικούς τύπους δεδομένων, | ||
| <code java Box.java> | <code java Box.java> | ||
| Line 50: | Line 71: | ||
| Η παραπάνω δήλωση της κλάσης //Box// σημαίνει ότι κατά τον ορισμό αντικειμένων της κλάσης αυτά θα πρέπει να προσδιορίζεται ανάμεσα στους χαρακτήρες '<', | Η παραπάνω δήλωση της κλάσης //Box// σημαίνει ότι κατά τον ορισμό αντικειμένων της κλάσης αυτά θα πρέπει να προσδιορίζεται ανάμεσα στους χαρακτήρες '<', | ||
| + | |||
| <code java> | <code java> | ||
| Box< | Box< | ||
| Line 55: | Line 77: | ||
| Box< | Box< | ||
| </ | </ | ||
| + | |||
| Ο τύπος δεδομένων που χρησιμοποιούμε ανάμεσα στους χαρακτήρες '<', | Ο τύπος δεδομένων που χρησιμοποιούμε ανάμεσα στους χαρακτήρες '<', | ||
| - | ===== Ονοματολογία παραμέτρων ===== | + | ===== Συνήθης ονοματολογία παραμέτρων ===== |
| * E - Element (χρησιμοποείται στο Java Collections Framework) | * E - Element (χρησιμοποείται στο Java Collections Framework) | ||
| Line 89: | Line 112: | ||
| Note: Recompile with -Xlint: | Note: Recompile with -Xlint: | ||
| </ | </ | ||
| - | |||
| - | ===== Interfaces ως παραμετρικοί τύποι δεδομένων ===== | ||
| - | |||
| - | Εκτός από κλάσεις μπορούμε να ορίσουμε και διεπαφές ως παραμετρικούς τύπους. Το interface Stack που ορίζεται παρακάτω είναι ένα παράδειγμα παραμετρικού interface το οποίο προδιαγράφει τη λειτουργία της στοίβας. | ||
| - | |||
| - | <code java Stack.java> | ||
| - | interface Stack <T> { | ||
| - | public int size(); | ||
| - | public boolean isEmpty(); | ||
| - | public void push(T obj); | ||
| - | public T pop(); | ||
| - | public T top(); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Το interface δηλώνει ότι η στοίβα λαμβάνει ως όρισμα ένα τύπο δεδομένων που αντιστοιχεί στα αντικείμενα που αποθηκεύονται σε αυτή. | ||
| - | |||
| - | Άλλο παράδειγμα παραμετρικού interface είναι το [[https:// | ||
| - | |||
| - | <code java> | ||
| - | interface Comparable< | ||
| - | int compareTo(T o) | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Παραμετρικοί τύποι δεδομένων με πολλές παραμέτρους ===== | ||
| - | |||
| - | Δείτε το παρακάτω παράδειγμα, | ||
| - | |||
| - | <code java Pair.java> | ||
| - | public interface Pair<K, V> { | ||
| - | public K getKey(); | ||
| - | public V getValue(); | ||
| - | public void setKey(K key); | ||
| - | public void setValue(V value); | ||
| - | } | ||
| - | </ | ||
| - | <code java OrderedPair.java> | ||
| - | public class OrderedPair< | ||
| - | |||
| - | private K key; | ||
| - | private V value; | ||
| - | |||
| - | public OrderedPair(K key, V value) { | ||
| - | this.key = key; | ||
| - | this.value = value; | ||
| - | } | ||
| - | |||
| - | public void setKey(K key) { this.key = key; } | ||
| - | public void setValue(V value) { this.value = value; } | ||
| - | public K getKey() | ||
| - | public V getValue() { return value; } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Με βάση τον παραπάνω κώδικα μπορείτε να δημιουργήσετε αντικείμενα επιμέρους τύπων ως εξής: | ||
| - | <code java OrderedPairUsage.java> | ||
| - | public class OrderedPairUsage { | ||
| - | public static void main(String args[]) { | ||
| - | Pair< | ||
| - | Pair< | ||
| - | OrderedPair< | ||
| - | // the following is not allowed | ||
| - | Pair< | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Απλοί παραμετρικοί τύποι δεδομένων (Raw Generic Types) ===== | ||
| - | |||
| - | Όπως δείξαμε προηγούμενα, | ||
| - | |||
| - | <code java> | ||
| - | Box b = new Box(); | ||
| - | </ | ||
| - | |||
| - | Σε αυτή την περίπτωση καταλήγουμε να έχουμε έναν μη-παραμετρικό τύπο δεδομένων. Ο μεταγλωττιστής δεν είναι σε θέση να γνωρίζει τον τύπο δεδομένων που θα τοποθετήσετε στο συγκεκριμένο αντικείμενο. Ουσιαστικά η παραπάνω δήλωση ισοδυναμεί με μία δήλωση της μορφής. | ||
| - | |||
| - | <code java> | ||
| - | Box< | ||
| - | </ | ||
| - | |||
| - | Η προσπάθεια μεταγλώττισης του παρακάτω κώδικα καταδεικνύει το παραπάνω | ||
| - | <code java BoxUsage.java> | ||
| - | public class BoxUsage { | ||
| - | | ||
| - | Box b = new Box(5); | ||
| - | | ||
| - | | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Το μήνυμα που εμφανίζει ο μεταγλωττιστής για τον παραπάνω κώδικα είναι το εξής: | ||
| - | < | ||
| - | $> javac BoxUsage.java | ||
| - | BoxUsage.java: | ||
| - | | ||
| - | ^ | ||
| - | required: Number | ||
| - | found: Object | ||
| - | reason: actual argument Object cannot be converted to Number by method invocation conversion | ||
| - | where T is a type-variable: | ||
| - | T extends Object declared in class Box | ||
| - | Note: BoxUsage.java uses unchecked or unsafe operations. | ||
| - | Note: Recompile with -Xlint: | ||
| - | 1 error | ||
| - | </ | ||
| - | |||
| - | Αν αλλάξετε την γραμμή '' | ||
| - | |||
| - | Η μη χρήση των παραμετρικών τύπων δεδομένων δυσκολεύει τον μεταγλωττιστή να αποφασίσει για την ασφαλή ή μη ασφαλή χρήση των δεδομένων που θα αποθηκευτούν στην κλάση. Δείτε τα παρακάτω παραδείγματα κώδικα | ||
| - | |||
| - | <code java> | ||
| - | Box< | ||
| - | Box rawBox = stringBox; | ||
| - | </ | ||
| - | |||
| - | <code java> | ||
| - | Box rawBox = new Box(); | ||
| - | Box< | ||
| - | </ | ||
| - | |||
| - | <code java> | ||
| - | Box< | ||
| - | Box rawBox = stringBox; | ||
| - | rawBox.set(8); | ||
| - | </ | ||
| - | |||
| - | |||
| - | ==== Unchecked Error Messages ==== | ||
| - | |||
| - | Όπως είπαμε προηγούμενα η μίξη generics με raw types μπορεί να δημιουργήσει warnings κατά την μεταγλώττιση της μορφής | ||
| - | < | ||
| - | Note: Example.java uses unchecked or unsafe operations. | ||
| - | Note: Recompile with -Xlint: | ||
| - | </ | ||
| - | όπως παρακάτω | ||
| - | <code java WarningDemo.java> | ||
| - | public class WarningDemo { | ||
| - | public static void main(String[] args){ | ||
| - | Box< | ||
| - | bi = createBox(); | ||
| - | } | ||
| - | |||
| - | static Box createBox(){ | ||
| - | return new Box(); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | Μεταγλωττίζοντας με το flag '' | ||
| - | < | ||
| - | WarningDemo.java: | ||
| - | found : Box | ||
| - | required: Box< | ||
| - | bi = createBox(); | ||
| - | ^ | ||
| - | 1 warning | ||
| - | </ | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| + | | Προηγούμενο: | ||
java/generics.1486478651.txt.gz · Last modified: 2017/02/07 14:44 (external edit)
