User Tools

Site Tools


java:generics_raw

This is an old revision of the document!


Απλοί παραμετρικοί τύποι δεδομένων (Raw Generic Types)

Όπως δείξαμε προηγούμενα, τα αντικείμενα της κλάσης Box ορίζονται σε συνδυασμό με ένα reference τύπο δεδομένων. Υπάρχει η δυνατότητα να ορίσετε ένα αντικείμενο της κλάσης Box χωρίς την χρήση της επιπλέον παραμέτρου, όπως παρακάτω.

Box b = new Box();

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

Box<Object> b = new Box<Object>();

Η προσπάθεια μεταγλώττισης του παρακάτω κώδικα καταδεικνύει το παραπάνω

BoxUsage.java
public class BoxUsage {
   public static void main(String args[]) {
     Box b = new Box(5);
     Box<Number> bn = new Box<>();
     bn.set(b.get());     
   }
}

Το μήνυμα που εμφανίζει ο μεταγλωττιστής για τον παραπάνω κώδικα είναι το εξής:

$> javac BoxUsage.java 
BoxUsage.java:5: error: method set in class Box<T> cannot be applied to given types;
     bn.set(b.get());     
       ^
  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:unchecked for details.
1 error

Αν αλλάξετε την γραμμή Box<Number> bn = new Box<>(); σε Box<Object> bn = new Box<>(); το λάθος μεταγλώττισης εξαφανίζεται και εμφανίζεται ένα warning που επισημαίνει ότι στην γραμμή 3 χρησιμοποιείται ένας παραμετρικός τύπος ως απλός (raw generic type).

Unchecked Error Messages

Η μη χρήση των παραμετρικών τύπων δεδομένων δυσκολεύει τον μεταγλωττιστή να αποφασίσει για την ασφαλή ή μη ασφαλή χρήση των δεδομένων που θα αποθηκευτούν στην κλάση. Η μίξη generics με raw types μπορεί να δημιουργήσει warnings της παρακάτω μορφής κατά την μεταγλώττιση.

Note: Example.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Δείτε τα παρακάτω παραδείγματα κώδικα

Box<String> stringBox = new Box<>();
Box rawBox = stringBox;           // Safe - OK
Box rawBox = new Box();           // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox;     // warning: unchecked conversion
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8);                    // warning: unchecked invocation to set(T)

Το παρακάτω παράδειγμα είναι επίσης ενδεικτικό:

WarningDemo.java
public class WarningDemo {
    public static void main(String[] args){
        Box<Integer> bi;
        bi = createBox();
    }
 
    static Box createBox(){
        return new Box();
    }
}

Μεταγλωττίζοντας με το flag -Xlint:unchecked εμφανίζεται το παρακάτω μήνυμα.

WarningDemo.java:4: warning: [unchecked] unchecked conversion
found   : Box
required: Box<java.lang.Integer>
        bi = createBox();
                      ^
1 warning
java/generics_raw.1486479770.txt.gz · Last modified: 2017/02/07 15:02 by gthanos