java generics tutorial with examples
Το Java Generics είναι ένα σύνολο χαρακτηριστικών που σας επιτρέπουν να γράφετε κώδικα ανεξάρτητα από τον τύπο δεδομένων. Αυτό το άρθρο εξηγεί το Java Generics λεπτομερώς με παραδείγματα:
Τα Generics είναι ένα από τα σημαντικά χαρακτηριστικά της Java και εισήχθησαν από το Java 5 και μετά.
Εξ ορισμού, το Generics είναι ένα σύνολο χαρακτηριστικών της γλώσσας Java που επιτρέπουν στον προγραμματιστή να χρησιμοποιεί τύπους και λειτουργίες Generic και έτσι να διασφαλίζει την ασφάλεια τύπου.
Τι θα μάθετε:
Πώς λειτουργούν τα Generics στην Java;
Εάν έχετε εργαστεί με το C ++ στο παρελθόν, τότε το Java Generics είναι το ίδιο με τα πρότυπα στο C ++. Το Java Generics σάς επιτρέπει να συμπεριλάβετε μια παράμετρο στον ορισμό κλάσης / μεθόδου που θα έχει την τιμή ενός πρωτόγονου τύπου δεδομένων.
Για παράδειγμα, μπορείτε να έχετε μια γενική τάξη 'Array' ως εξής:
Κατηγορία κατηγορίας {….}
Πού είναι ο παραμετροποιημένος τύπος.
Στη συνέχεια, μπορείτε να δημιουργήσετε αντικείμενα για αυτήν την τάξη ως εξής:
Array int_array = new Array () Array char_array = new Array ();
Έτσι, δεδομένης μιας γενικής παραμετροποιημένης κλάσης, μπορείτε να δημιουργήσετε αντικείμενα της ίδιας κλάσης με διαφορετικούς τύπους δεδομένων ως παραμέτρους. Αυτή είναι η κύρια ουσία της χρήσης Java Generics.
Ομοίως, μπορείτε να γράψετε μια γενική μέθοδο με έναν παραμετροποιημένο τύπο για την ταξινόμηση ενός πίνακα και στη συνέχεια να δημιουργήσετε αυτήν τη μέθοδο σε οποιονδήποτε πρωτόγονο τύπο.
Τα Java Generics χρησιμοποιούνται κυρίως με το πλαίσιο συλλογών της Java. Οι διαφορετικές συλλογές όπως LinkedList, List, Map, HashMap κ.λπ. χρησιμοποιούν το Generics για υλοποίηση. Τα Generics παρέχουν ασφάλεια τύπου καθώς ο έλεγχος τύπου γίνεται κατά το χρόνο μεταγλώττισης, καθιστώντας τον κώδικα πιο σταθερό.
Ας δούμε τώρα περισσότερο τις λεπτομέρειες των γενικών τάξεων και μεθόδων, καθώς και άλλων σχετικών θεμάτων.
Γενικές τάξεις
Μια γενική κλάση είναι η ίδια με μια κανονική τάξη, εκτός από το ότι το όνομα κλάσης ακολουθείται από έναν τύπο σε γωνιακές αγκύλες.
Ένας γενικός ορισμός μιας γενικής κλάσης είναι ο εξής:
class_name τάξης
{
μεταβλητές τάξης
… ..
μέθοδοι τάξης?
}
Μόλις οριστεί η τάξη, μπορείτε να δημιουργήσετε αντικείμενα οποιουδήποτε τύπου δεδομένων που θέλετε ως εξής:
class_name obj = new class_name ();
Για παράδειγμα, για αντικείμενο Integer η δήλωση θα είναι:
class_name obj = new class_name;
Ομοίως, για τον τύπο δεδομένων String, το αντικείμενο θα είναι:
class_name str_Obj = new class_name;
Ένα παράδειγμα εφαρμογής για την γενική τάξη φαίνεται παρακάτω.
class MyGenericClass { T obj; void add(T obj) { this.obj=obj; } T get() { return obj; } } class Main { public static void main(String args()) { MyGenericClass m_int=new MyGenericClass(); m_int.add(2); MyGenericClassmstr=new MyGenericClass(); mstr.add('SoftwaretestingHelp'); System.out.println('Member of MyGenericClass:' + m_int.get()); System.out.println('Member of MyGenericClass:' + mstr.get()); } }
Παραγωγή:
Στο παραπάνω πρόγραμμα, μια τάξη MyGenericClass είναι μια γενική τάξη. Έχει δύο μεθόδους, δηλαδή προσθήκη και λήψη. Η μέθοδος add αρχικοποιεί το γενικό αντικείμενο ενώ οι μέθοδοι get επιστρέφουν το αντικείμενο.
τι είναι η λειτουργία φίλου στο c ++
Στην κύρια συνάρτηση, δηλώνουμε δύο αντικείμενα τύπου Integer και String το καθένα. Αρχικοποιούμε και τα δύο αυτά αντικείμενα με τις αντίστοιχες αρχικές τιμές τους χρησιμοποιώντας τη μέθοδο προσθήκης και στη συνέχεια εξάγουμε τα περιεχόμενα αυτών των αντικειμένων χρησιμοποιώντας τη μέθοδο get.
Παρουσιάσαμε το παραπάνω γενικό παράδειγμα κατηγορίας με μία παράμετρο τύπου. Στην πραγματικότητα, όμως, μια τάξη μπορεί να έχει περισσότερες από μία παραμέτρους τύπου. Σε αυτήν την περίπτωση, οι παράμετροι τύπου διαχωρίζονται με κόμμα.
Το ακόλουθο παράδειγμα το αποδεικνύει:
classTest_Generics { T1 obj1; // An object of type T1 T2 obj2; // An object of type T2 // constructor to initialise T1 & T2 objects Test_Generics(T1 obj1, T2 obj2) { this.obj1 = obj1; this.obj2 = obj2; } public void print() { System.out.println('T1 Object:' + obj1); System.out.println('T2 Object:' + obj2); } } class Main { public static void main (String() args) { Test_Genericsobj = newTest_Generics('Java Generics', 1); obj.print(); } }
Παραγωγή:
Σε αυτό το πρόγραμμα, έχουμε δύο παραμέτρους τύπου, δηλαδή T1 και T2. Έχουμε λειτουργίες για την αρχικοποίηση των αντικειμένων μελών και επίσης για την εκτύπωση των περιεχομένων. Στην κύρια συνάρτηση, δηλώνουμε ένα αντικείμενο με δύο τύπους, δηλαδή String και Integer. Η έξοδος του προγράμματος δείχνει το περιεχόμενο του αντικειμένου που δημιουργήθηκε.
Όπως και τα μαθήματα, μπορείτε επίσης να έχετε γενικές διεπαφές. Θα μάθουμε τα πάντα για τις διεπαφές σε ένα ξεχωριστό θέμα.
Γενικές μέθοδοι Java
Ακριβώς όπως μπορείτε να έχετε γενικές τάξεις και διεπαφές, μπορείτε επίσης να έχετε γενικές μεθόδους σε περίπτωση που δεν χρειάζεστε μια ολόκληρη τάξη για να είναι Γενική.
Το παρακάτω πρόγραμμα δείχνει την εφαρμογή της γενικής μεθόδου 'printGenericArray'. Σημειώστε την κλήση μεθόδου στην κύρια λειτουργία. Εδώ κάνουμε δύο κλήσεις στη γενική μέθοδο, πρώτη φορά με τύπο και στη συνέχεια με τύπο.
public class Main{ public static void printGenericArray(T() items) { for ( T item : items){ System.out.print(item + ' '); } System.out.println(); } public static void main( String args() ) { Integer() int_Array = { 1, 3, 5, 7, 9, 11 }; Character() char_Array = { 'J', 'A', 'V', 'A', 'T','U','T','O','R','I','A', 'L','S' }; System.out.println( 'Integer Array contents:' ); printGenericArray(int_Array ); System.out.println( 'Character Array contents:' ); printGenericArray(char_Array ); } }
Παραγωγή:
Οριακές παράμετροι τύπου
Οι παράμετροι Bounded Type εμφανίζονται στην εικόνα όταν θέλετε να περιορίσετε τους τύπους δεδομένων στο Generics. Για παράδειγμα, Αν θέλετε μια συγκεκριμένη γενική κλάση ή μέθοδο ή οποιαδήποτε διεπαφή που θα πρέπει να λειτουργεί μόνο για αριθμητικούς τύπους δεδομένων, τότε μπορείτε να καθορίσετε ότι χρησιμοποιώντας τη λέξη-κλειδί 'επεκτείνεται'.
Αυτό φαίνεται παρακάτω:
Ποια είναι η καλύτερη εφαρμογή κατασκοπίας κινητού τηλεφώνου
List myList = new ArrayList(); List list1 = new ArrayList();
Οι παραπάνω δύο δηλώσεις θα γίνουν αποδεκτές από τον μεταγλωττιστή καθώς οι Long και Integer είναι υποκατηγορίες του Number.
Η επόμενη δήλωση, ωστόσο, θα είναι πρόβλημα.
List list = new ArrayList();
Αυτό θα δώσει σφάλμα χρόνου μεταγλώττισης επειδή το String δεν είναι αριθμός. Το σύμβολο «?» Στο παραπάνω παράδειγμα είναι γνωστό ως μπαλαντέρ και θα το συζητήσουμε στη συνέχεια.
Έτσι, γενικά, οι παράμετροι οριοθετημένου τύπου χρησιμοποιούνται κυρίως όταν θέλετε να περιορίσετε τους τύπους δεδομένων που θα χρησιμοποιηθούν στον κώδικα γενικής χρήσης.
Μπαλαντέρ Java Generics
Στην Ιάβα, μια μπαλαντέρ συμβολίζεται με ένα ερωτηματικό, «?» Που χρησιμοποιείται για αναφορά σε έναν άγνωστο τύπο. Οι χαρακτήρες μπαλαντέρ χρησιμοποιούνται ως επί το πλείστον με γενικά ως τύπος παραμέτρου.
Όταν χρησιμοποιείτε Generic Wildcards, πρέπει να θυμάστε ένα σημείο ότι παρόλο που το αντικείμενο είναι το superclass όλων των άλλων τάξεων, η συλλογή αντικειμένων ( Για παράδειγμα, List) δεν είναι ένα superclass όλων των άλλων συλλογών.
Εκτός από τη χρήση ως τύπο παραμέτρου, μπορείτε να χρησιμοποιήσετε ένα μπαλαντέρ ως πεδίο, μια τοπική μεταβλητή και ως τέτοια. Ωστόσο, δεν μπορείτε ποτέ να χρησιμοποιήσετε μια μπαλαντέρ ως supertype ή ως όρισμα τύπου για να επικαλεστείτε μια γενική μέθοδο ή σε περίπτωση δημιουργίας μιας παρουσίας μιας γενικής κλάσης.
Υπάρχουν πολλά παραδείγματα παραμετροποιημένων τύπων μπαλαντέρ (εδώ τουλάχιστον ένα όρισμα τύπου είναι μπαλαντέρ) όπως φαίνεται παρακάτω και οι χαρακτήρες μπαλαντέρ που χρησιμοποιούνται σε διαφορετικά μέρη θα ερμηνεύονται διαφορετικά:
- Συλλογή <: Η συλλογή υποδηλώνει όλες τις παραμέτρους διεπαφής συλλογής ανεξάρτητα από τον τύπο ορίσματος που χρησιμοποιείται.
- Λίστα extends Number< : Η λίστα αντιπροσωπεύει όλους τους τύπους λίστας όπου ο τύπος στοιχείου θα είναι ένας αριθμός.
- Συγκριτής: Όλες οι καταστάσεις διεπαφής σύγκρισης για ορίσματα τύπου που είναι Stringsupertypes.
Σημειώστε ότι ένας χαρακτήρας παραμέτρων μπαλαντέρ είναι ένας κανόνας που επιβάλλεται για την αναγνώριση έγκυρων τύπων. Δεν είναι συγκεκριμένος τύπος δεδομένων. Οι γενικές μπαλαντέρ μπορούν να είναι οριοθετημένες ή χωρίς περιορισμούς.
# 1) Χωρίς περιορισμούς μπαλαντέρ
Στο Unbounded Wildcards, δεν υπάρχουν περιορισμοί στις μεταβλητές τύπου και δηλώνεται ως εξής:
ArrayList mylist = new ArrayList(); ArrayList my_strList = new ArrayList();
# 2) Οριοθετημένα μπαλαντέρ
Έχουμε ήδη συζητήσει τους περιορισμένους τύπους. Αυτοί θέτουν τους περιορισμούς στον τύπο δεδομένων που χρησιμοποιείται για την παρουσίαση των παραμέτρων τύπου χρησιμοποιώντας τις λέξεις-κλειδιά - επεκτείνεται ή υπερ. Αυτοί οι χαρακτήρες μπαλαντέρ μπορούν να χωριστούν περαιτέρω σε Wildcounded Upper Bounded και Wild Wildcard.
- Άγριοι Wildcards
Εάν θέλετε η γενική σας έκφραση να είναι έγκυρη για όλες τις υποκατηγορίες ενός δεδομένου τύπου, τότε καθορίζετε την Άνω μπαλαντέρ μπαλαντέρ με τη λέξη-κλειδί επεκτείνεται.
Για παράδειγμα, ας υποθέσουμε ότι χρειάζεστε μια γενική μέθοδο που υποστηρίζει Λίστα, Λίστα κ.λπ., τότε μπορείτε να καθορίσετε μια Άγρια Κάρτα Wild Λίστα . Καθώς το Number είναι ένα superclass, αυτή η γενική μέθοδος θα λειτουργήσει για όλες τις υποκατηγορίες της.
Το παρακάτω πρόγραμμα το αποδεικνύει.
importjava.util.*; public class Main { private static Number summation (List numbers){ double sum = 0.0; for (Number n : numbers) sum += n.doubleValue(); return sum; } public static void main(String() args) { //Number subtype : Integer Listint_list = Arrays.asList(1,3,5,7,9); System.out.println('Sum of the elements in int_list:' + summation(int_list)); //Number subtype : Double List doubles_list = Arrays.asList(1.0,1.5,2.0,2.5,3.0,3.5); System.out.println('Sum of the elements in doubles_list:' + summation(doubles_list)); } }
Παραγωγή:
Εδώ παρέχουμε ένα άνω μπαλαντέρ, Λίστα στο όρισμα τύπου της συνάρτησης «άθροισμα». Στην κύρια συνάρτηση, ορίζουμε δύο λίστες, δηλαδή int_list του τύπου Integer και doubles_list του τύπου Double. Καθώς το Integer και το Double είναι οι υποκατηγορίες του Number, το άθροισμα της συνάρτησης λειτουργεί τέλεια και στις δύο αυτές λίστες.
- Κάτω μπαλαντέρ μπαλαντέρ
Εάν θέλετε η γενική έκφραση να αποδεχτεί όλα τα superclasses ενός συγκεκριμένου τύπου, τότε μπορείτε να καθορίσετε ένα μπαλαντέρ με χαμηλότερο όριο για το όρισμα τύπου.
Ένα παράδειγμα εφαρμογής για αυτό δίνεται παρακάτω:
importjava.util.*; class Main { public static void main(String() args) { //Integer List ListInt_list= Arrays.asList(1,3,5,7); System.out.print('Integer List:'); printforLowerBoundedWildcards(Int_list); //Number list ListNumber_list= Arrays.asList(2,4,6,8); System.out.print('Number List:'); printforLowerBoundedWildcards(Number_list); } public static void printforLowerBoundedWildcards(List list) { System.out.println(list); } }
Παραγωγή:
Σε αυτό το πρόγραμμα, το Wild Barded Wildcard που καθορίζεται είναι «Λίστα». Στη συνέχεια, στην κύρια λειτουργία, έχουμε μια λίστα τύπων και τη λίστα. Καθώς έχουμε χρησιμοποιήσει το Wild Barded Wildcard, η κλάση αριθμών είναι ένα superclass του Integer είναι ένα όρισμα έγκυρου τύπου.
Πλεονεκτήματα της Java Generics
# 1) Ασφάλεια τύπου
Τα Generics διασφαλίζουν την ασφάλεια τύπου. Αυτό σημαίνει ότι ο έλεγχος τύπου γίνεται κατά τον χρόνο μεταγλώττισης και όχι κατά τον χρόνο εκτέλεσης. Έτσι, δεν υπάρχει πιθανότητα να λάβετε το 'ClassCastException' κατά τη διάρκεια του χρόνου εκτέλεσης καθώς θα χρησιμοποιηθούν σωστοί τύποι.
importjava.util.*; class Main { public static void main(String() args) { List mylist = new ArrayList(); mylist.add(10); mylist.add('10'); System.out.println(mylist); List list = new ArrayList(); list.add(10); list.add('10');// compile-time error System.out.println(list); } }
Στο παραπάνω πρόγραμμα, έχουμε δύο λίστες, μία χωρίς γενικά και μια άλλη με γενικά. Στη μη γενική λίστα, δεν υπάρχει ασφάλεια τύπου. Μπορείτε να προσθέσετε έναν ακέραιο, συμβολοσειρά κ.λπ. ως στοιχείο και είναι αποδεκτό.
Στη γενική λίστα, μπορείτε να προσθέσετε μόνο έναν τύπο στοιχείου που καθορίζεται στη γενική έκφραση. Εάν επιχειρήσετε να προσθέσετε ένα στοιχείο άλλου τύπου, τότε αυτό οδηγεί σε σφάλμα χρόνου μεταγλώττισης.
Στο παραπάνω πρόγραμμα αναβοσβήνει το σφάλμα χρόνου μεταγλώττισης στη γραμμή:
list.add('10');
# 2) Επαναχρησιμοποίηση κώδικα
Χρησιμοποιώντας το Generics, δεν χρειάζεται να γράψετε ξεχωριστό κώδικα για κάθε τύπο δεδομένων. Μπορείτε να γράψετε μια κατηγορία ή μια μέθοδο κ.λπ. και να τη χρησιμοποιήσετε για όλους τους τύπους δεδομένων.
# 3) Δεν υπάρχει ανάγκη για πληκτρολόγηση
Καθώς χρησιμοποιείτε το Generics, ο μεταγλωττιστής γνωρίζει για τους τύπους που χρησιμοποιούνται και, στη συνέχεια, δεν υπάρχει ανάγκη για πληκτρολόγηση.
Εξετάστε τον παρακάτω κώδικα:
List mylist = new ArrayList(); mylist.add('Java'); String mystr = (String) list.get(0); //typecasting required
Όπως μπορείτε να δείτε πότε χρησιμοποιείται μια κανονική λίστα, πρέπει να πληκτρολογήσετε το στοιχείο λίστας στον κατάλληλο τύπο με τον τρόπο που γίνεται για το παραπάνω μυστήριο.
Τώρα ας γράψουμε ξανά τον ίδιο κωδικό με μια γενική λίστα.
List list = new ArrayList(); list.add('Java'); String mystr = list.get(0);
Εδώ, έχουμε καθορίσει τον τύπο συμβολοσειράς ως γενική έκφραση για τη δήλωση λίστας. Επομένως, για να ανακτήσουμε μεμονωμένα στοιχεία αυτής της λίστας, δεν χρειάζεται να πληκτρολογήσουμε.
# 4) Εφαρμογή γενικών αλγορίθμων
Μπορείτε να εφαρμόσετε πολύ περισσότερους γενικούς αλγόριθμους όταν χρησιμοποιείτε το Generics για κωδικοποίηση.
# 5) Έλεγχος χρόνου μεταγλώττισης
Όπως ήδη αναφέρθηκε, όταν χρησιμοποιείτε το Generics στο πρόγραμμα Java, ο μεταγλωττιστής ελέγχει τους τύπους κατά τη στιγμή της μεταγλώττισης, αποτρέποντας έτσι τον μη φυσιολογικό τερματισμό του προγράμματος κατά το χρόνο εκτέλεσης.
Συχνές Ερωτήσεις
Ε # 1) Γιατί χρησιμοποιούμε Generics στην Java;
Απάντηση: Τα Generics διασφαλίζουν την ανεξαρτησία του τύπου, δηλαδή μπορούμε να παρέχουμε μια παράμετρο τύπου κατά τον καθορισμό μιας κλάσης / διεπαφής / μεθόδου κ.λπ. έτσι ώστε κατά τη διάρκεια της πραγματικής παρουσίας να μπορούμε να καθορίσουμε τον πραγματικό τύπο. Με αυτόν τον τρόπο παρέχουμε επίσης επαναχρησιμοποίηση κώδικα.
Ε # 2) Είναι τα Generics σημαντικά στην Java;
Απάντηση: Ναί. Στην πραγματικότητα, τα Generics είναι τα πιο σημαντικά χαρακτηριστικά της Java για να διασφαλιστεί η ασφάλεια τύπου, δηλαδή ο έλεγχος τύπου compile-time.
εφαρμογή για κατασκοπεία στο τηλέφωνο Android
Q # 3) Πότε πρόσθεσε η Java Generics;
Απάντηση: Generics προστέθηκαν στην Java το 2004 με J2SE 5.0 με σκοπό να διασφαλιστεί η ασφάλεια τύπου compile-time στην Java.
Q # 4) Τι είναι ένας γενικός τύπος;
Απάντηση: Ένας γενικός τύπος είναι μια γενική κλάση, διεπαφή ή μέθοδος που παρέχεται με μια παράμετρο τύπου. Αυτό επιτρέπει την ασφάλεια τύπου και την επαναχρησιμοποίηση κώδικα.
Ε # 5) Μπορούμε να χρησιμοποιήσουμε το Generics with Array στην Java;
Απάντηση: Όχι. Η Java δεν επιτρέπει γενικές συστοιχίες.
συμπέρασμα
Αυτό ολοκληρώνει το σεμινάριο για τα γενικά Java που θεωρείται ως ένα από τα πιο σημαντικά χαρακτηριστικά στις πρόσφατες εκδόσεις Java. Η χρήση των Generics σε προγράμματα Java διασφαλίζει την ασφάλεια του τύπου καθώς και την επαναχρησιμοποίηση κώδικα. Εξασφαλίζει επίσης τον έλεγχο του χρόνου μεταγλώττισης, έτσι ώστε το πρόγραμμα να μην διακόπτεται κατά την εκτέλεση.
Τα γενικά Java λειτουργούν κυρίως με τη διεπαφή συλλογών Java που θα συζητήσουμε λεπτομερώς σε ένα άλλο σεμινάριο αυτής της σειράς.
Καλή ανάγνωση !!
Συνιστώμενη ανάγνωση
- 15 καλύτερα εργαλεία JAVA για ανάπτυξη, κατασκευή, προφίλer, κάλυψη κώδικα και κριτική
- Εκμάθηση Java Συλλογές Πλαίσιο (JCF)
- Java DataTypes, Loops, Arrays, Switch και Assertions
- Ανάπτυξη Java: Δημιουργία και εκτέλεση αρχείου Java JAR
- Java Εξαιρέσεις και Χειρισμός Εξαιρέσεων με Παραδείγματα
- Εκπαιδευτικό πρόγραμμα JAVA για αρχάριους: 100+ πρακτικά εκπαιδευτικά βίντεο Java
- Εκμάθηση Java Reflection με παραδείγματα
- Java «αυτό» Λέξη-κλειδί: Εκμάθηση με παραδείγματα κώδικα