Java Εκμάθηση Reflection API με παράδειγμα

Τι είναι το Reflection σε Java?

Java Το Reflection είναι η διαδικασία ανάλυσης και τροποποίησης όλων των δυνατοτήτων μιας κλάσης κατά το χρόνο εκτέλεσης. Reflection API in Java χρησιμοποιείται για τον χειρισμό της κλάσης και των μελών της που περιλαμβάνουν πεδία, μεθόδους, κατασκευαστή κ.λπ. κατά το χρόνο εκτέλεσης.

Ένα πλεονέκτημα του Reflection API in Java δηλαδή, μπορεί να χειραγωγήσει και ιδιωτικά μέλη της τάξης.

Το πακέτο java.lang.reflect παρέχει πολλές κλάσεις για την υλοποίηση java ανάκλασης. Μέθοδοι της κλάσης java.lang.Class χρησιμοποιούνται για τη συλλογή των πλήρων μεταδεδομένων μιας συγκεκριμένης κλάσης.

Κατηγορία στο java.lang.reflect Package

Ακολουθεί μια λίστα με διάφορα Java τάξεις στο java.lang.package για την υλοποίηση του προβληματισμού-

  • Πεδίο: Αυτή η κλάση χρησιμοποιείται για τη συλλογή δηλωτικών πληροφοριών όπως τύπος δεδομένων, τροποποιητής πρόσβασης, όνομα και τιμή μεταβλητής.
  • Μέθοδος: Αυτή η κλάση χρησιμοποιείται για τη συλλογή δηλωτικών πληροφοριών όπως τροποποιητής πρόσβασης, τύπος επιστροφής, όνομα, τύποι παραμέτρων και τύπος εξαίρεσης μιας μεθόδου.
  • Κατασκευαστής: Αυτή η κλάση χρησιμοποιείται για τη συλλογή δηλωτικών πληροφοριών όπως τροποποιητή πρόσβασης, όνομα και τύπους παραμέτρων ενός κατασκευαστή.
  • Αλλαγή: Αυτή η κλάση χρησιμοποιείται για τη συλλογή πληροφοριών σχετικά με έναν συγκεκριμένο τροποποιητή πρόσβασης.

Μέθοδοι που χρησιμοποιούνται στο java.lang.Class

  • Δημόσια συμβολοσειρά getName (): Επιστρέφει το όνομα της τάξης.
  • δημόσια τάξη getSuperclass(): Επιστρέφει την αναφορά super class
  • Δημόσια τάξη[] getInterfaces() : Επιστρέφει έναν πίνακα διεπαφών που υλοποιούνται από την καθορισμένη κλάση
  • Δημόσιο στο getModifiers (): Επιστρέφει μια ακέραια τιμή που αντιπροσωπεύει τους τροποποιητές της καθορισμένης κλάσης η οποία πρέπει να μεταβιβαστεί ως παράμετρος στο "δημόσια στατική συμβολοσειρά toString (int i )” μέθοδος που επιστρέφει τον προσδιοριστή πρόσβασης για τη δεδομένη κλάση.

Πώς να λάβετε πλήρεις πληροφορίες για μια τάξη

Για να λάβετε πληροφορίες για μεταβλητές, μεθόδους και κατασκευαστές μιας κλάσης, πρέπει να δημιουργήσουμε ένα αντικείμενο της κλάσης.

Μέθοδοι που χρησιμοποιούνται στο java.lang.Class

public class Guru99ClassObjectCreation {
	public static void main (String[] args) throws ClassNotFoundException {
		//1 - By using Class.forname() method 
		Class c1 = Class.forName("Guru99ClassObjectCreation"); 
		//2- By using getClass() method 
		Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
		Class c2 = guru99Obj.getClass();
		//3- By using .class 
		Class c3= Guru99ClassObjectCreation.class;
		}
	}
  • Το παρακάτω παράδειγμα δείχνει διαφορετικούς τρόπους δημιουργίας αντικειμένου κλάσης "class" :
  • Παράδειγμα 1: Πώς να αποκτήσετε Μεταδεδομένα Τάξης

    Το παρακάτω παράδειγμα δείχνει πώς να λαμβάνετε μεταδεδομένα όπως: Όνομα κλάσης, όνομα σούπερ κλάσης, υλοποιημένες διεπαφές και τροποποιητές πρόσβασης μιας κλάσης.

    Θα λάβουμε τα μεταδεδομένα της παρακάτω κατηγορίας που ονομάζεται Guru99Base.class:

    Λάβετε μεταδεδομένα της τάξης

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. Το όνομα της τάξης είναι: Guru99Base
    2. Οι τροποποιητές πρόσβασης είναι: δημόσιοι και αφηρημένοι
    3. Έχει υλοποιήσει διεπαφές: Serializable και Cloneable
    4. Δεδομένου ότι δεν έχει επεκτείνει καμία κλάση ρητά, η σούπερ κλάση είναι: java.lang.Object

    Η παρακάτω τάξη θα λάβει τα μεταδεδομένα του Guru99Base.class και θα τα εκτυπώσει:

    Λάβετε μεταδεδομένα της τάξης

    import java.lang.reflect.Modifier;
    public class Guru99GetclassMetaData {
    
    	public static void main (String [] args) throws ClassNotFoundException { 
    	// Create Class object for Guru99Base.class 
    	Class guru99ClassObj = Guru99Base.class;
    	
    	// Print name of the class 
    	system.out.println("Name of the class is : " +guru99ClassObj.getName());
    	
    	// Print Super class name
    	system.out.println("Name of the super class is : " +guru99ClassObj.getSuperclass().getName());
    	
    	// Get the list of implemented interfaces in the form of Class array using getInterface() method
    	class[] guru99InterfaceList = guru99classObj.getInterfaces();
    	
    	// Print the implemented interfaces using foreach loop 
    	system.out.print("Implemented interfaces are : ");
    	for (Class guru99class1 : quru99 InterfaceList)	{
    		system.out.print guru99class1.getName() + " ");
    	}
    	system.out.println();
    	
    	//Get access modifiers using get Modifiers() method and toString() method of java.lang.reflect.Modifier class
    	int guru99AccessModifier= guru99classObj.getModifiers(); 
    	// Print the access modifiers
    	System.Out.println("Access modifiers of the class are : " +Modifier.tostring(guru99AccessModifier));
    	
    	}
    }
    
    1. εκτυπώστε το όνομα της κλάσης χρησιμοποιώντας τη μέθοδο getName
    2. Εκτυπώστε το όνομα της super class χρησιμοποιώντας τη μέθοδο getSuperClass().getName().
    3. Εκτυπώστε το όνομα των εφαρμοζόμενων διεπαφών
    4. Εκτυπώστε τους τροποποιητές πρόσβασης που χρησιμοποιούνται από την τάξη

    Λάβετε μεταδεδομένα της τάξης

    Λάβετε μεταδεδομένα της τάξης

    Παράδειγμα 2 : Πώς να αποκτήσετε μεταδεδομένα μεταβλητής

    Τα ακόλουθα παραδείγματα δείχνουν πώς μπορείτε να λάβετε μεταδεδομένα μεταβλητής:

    Εδώ, δημιουργούμε μια κλάση με το όνομα Guru99VariableMetaData .class με μερικές μεταβλητές:

    package guru;
    public class Guru99VariableMetaData {				
                   public static int guru99IntVar1=1111;
                   static int guru99IntVar2=2222;							
                   static String guru99StringVar1="guru99.com";							
                    static String guru99StringVar2="Learning Reflection API";    
    }	
    
    Βήματα για να λάβετε τα μεταδεδομένα σχετικά με τις μεταβλητές στην παραπάνω κλάση:
    1. Δημιουργήστε το αντικείμενο κλάσης της παραπάνω κλάσης, π.χ. Guru99VariableMetaData.class όπως παρακάτω:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Λάβετε τα μεταδεδομένα με τη μορφή πίνακα πεδίων χρησιμοποιώντας getFields() or getDeclaredFields() μεθόδους όπως παρακάτω:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields() Η μέθοδος επιστρέφει μεταδεδομένα της δημόσιας μεταβλητής από την καθορισμένη κλάση καθώς και από την υπερκλάση της.

    getDeclaredFields() μέθοδος επιστρέφει μεταδεδομένα όλων των μεταβλητών από την καθορισμένη κλάση μόνο.

    1. Λάβετε το όνομα των μεταβλητών χρησιμοποιώντας τη μέθοδο "public String getName()".
    2. Λάβετε τον τύπο δεδομένων των μεταβλητών χρησιμοποιώντας τη μέθοδο "public Class getType()".
    3. Λάβετε την τιμή της μεταβλητής χρησιμοποιώντας τη μέθοδο "public xxx get (Field)".

      Εδώ, το xxx θα μπορούσε να είναι ένα byte ή μικρότερο από κάθε τύπο τιμής που θέλουμε να ανακτήσουμε.

    4. Λάβετε τους τροποποιητές πρόσβασης των μεταβλητών χρησιμοποιώντας τις μεθόδους getModifier() και Modifier.toString(int i).

      Εδώ, γράφουμε μια κλάση για να λάβουμε τα μεταδεδομένα των μεταβλητών που υπάρχουν στην κλάση Guru99VariableMetaData .class:

      Λήψη μεταδεδομένων της μεταβλητής

      package guru;
      import java.lang.reflect.Field; 
      
      public class Guru99VariableMetaDataTest {
      	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { 
      	// Create Class object for Guru99VariableMetaData.class 
      	Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); 
      	Class guru99ClassObjVar = guru99ClassVar.getClass();
      	
      	// Get the metadata of all the fields of the class Guru99VariableMetaData 
      	Field[] guru99Field1= guru99ClassObjVar.getDeclaredFields();
      	
      	// Print name, datatypes, access modifiers and values of the varibales of the specified class 
      	for(Field field : guru99Field1) { 
      	System.out.println("Variable name : "+field.getName());
      	System.out.println("Datatypes of the variable :"+field.getType());
      	
      	int guru99AccessModifiers = field.getModifiers();
      	System.out.printlln("Access Modifiers of the variable : "+Modifier.toString(guru99AccessModifiers));
      	System.out.println("Value of the variable : "+field.get(guru99ClassVar));
      	System.out.println();
      	system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;
      	}
      	}
      }
      
      1. Δημιουργήθηκε αντικείμενο κλάσης για το Guru99VariableMetaData.class
      2. Λάβαμε όλα τα μεταδεδομένα των μεταβλητών σε έναν πίνακα Field
      3. Εκτύπωσε όλα τα ονόματα μεταβλητών στην κλάση Guru99VariableMetaData.class
      4. Εκτύπωσε όλους τους τύπους δεδομένων των μεταβλητών στην κλάση Guru99VariableMetaData.class
      5. Εκτύπωσε όλους τους τροποποιητές πρόσβασης των μεταβλητών στην κλάση Guru99VariableMetaData.class
      6. Εκτυπωμένες τιμές όλων των μεταβλητών στο Εκτυπώθηκαν όλοι οι τύποι δεδομένων των μεταβλητών στην κλάση Guru99VariableMetaData.class

      Λήψη μεταδεδομένων μεθόδου

      Λήψη μεταδεδομένων μεθόδου

      Παράδειγμα 3: Πώς να αποκτήσετε Μεταδεδομένα Μέθοδος

      Τα ακόλουθα παραδείγματα δείχνουν πώς μπορείτε να λάβετε μεταδεδομένα μιας μεθόδου:

      Εδώ, δημιουργούμε μια κλάση με το όνομα Guru99MethodMetaData .class με ορισμένες μεθόδους

      Λήψη μεταδεδομένων μεθόδου

      package guru;		
      import java.sql.SQLException;		
      public class Guru99MethodMetaData {   				
      
      	public void guru99Add(int firstElement, int secondElement , String result) 									
          throws ClassNotFoundException, ClassCastException{			
                System.out.println("Demo method for Reflextion  API");					
          }	
          public String guru99Search(String searchString) 			
          throws ArithmeticException, InterruptedException{			
              System.out.println("Demo method for Reflection API");					
      		return null;					
          }	
      	public void guru99Delete(String deleteString) 					
      	throws SQLException{			
      	    System.out.println("Demo method for Reflection API");					
          }	
      }

      Βήματα για να λάβετε τα μεταδεδομένα σχετικά με τις μεθόδους στην παραπάνω κλάση :

      1. Δημιουργήστε το αντικείμενο κλάσης της παραπάνω κλάσης, π.χ. Guru99MethodMetaData.class ως παρακάτω:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Λάβετε πληροφορίες μεθόδου σε έναν πίνακα μεθόδων χρησιμοποιώντας τη μέθοδο getMethods() και getDeclaredMethods() όπως παρακάτω:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        getMethods() Η μέθοδος επιστρέφει μεταδεδομένα των δημόσιων μεθόδων από την καθορισμένη κλάση καθώς και από την υπερκλάση της.

        getDeclaredMethods() μέθοδος επιστρέφει μεταδεδομένα όλων των μεθόδων από την καθορισμένη κλάση μόνο.

      3. Λάβετε το όνομα της μεθόδου που χρησιμοποιεί getName () μέθοδος.
      4. Λάβετε τον τύπο επιστροφής της μεθόδου χρησιμοποιώντας getReturnType() μέθοδος.
      5. Αποκτήστε πρόσβαση σε τροποποιητές των μεθόδων που χρησιμοποιούν getModifiers() και Modifiers.toString(int i) μεθόδους.
      6. Λάβετε τύπους παραμέτρων μεθόδου χρησιμοποιώντας getParameterTypes() μέθοδος που επιστρέφει έναν πίνακα κλάσης.
      7. Λάβετε εξαίρεση χρησιμοποιώντας getExceptionTypes() μέθοδος που επιστρέφει έναν πίνακα κλάσης.

      Εδώ, γράφουμε μια κλάση για να λάβουμε τα μεταδεδομένα των μεθόδων που υπάρχουν στην κλάση Guru99MethodMetaData.class:

      Λήψη μεταδεδομένων μεθόδου

      package guru;
      import java.lang.reflect.Method;
      import java.lang.reflect.Modifier;
      
      public class Guru99MethodMetaDataTest { 
      
      	public static void main (String[] args) {
      		// Create Class object for Guru99Method MetaData.class 
      		class guru99ClassObj = Guru99MethodMetaData.class;
      
      		// Get the metadata or information of all the methods of the class using getDeclaredMethods() 
      		Method[] guru99Methods=guru99classObj.getDeclaredMethods();
      
      		for(Method method : guru99Methods) { 
      		// Print the method names
      		System.out.println("Name of the method : "+method.getName());
      		
      		// Print return type of the methods 
      		System.out.println("Return type of the method : "+method.getReturnType());
      		
      		//Get the access modifier list and print
      		int guru99ModifierList = method.getModifiers(); 
      		System.Out.printlin ("Method access modifiers : "+Modifier.toString(guru99ModifierList));
      		
      		// Get and print parameters of the methods 
      		Class[] guru99ParamList= method.getParameterTypes(); 
      		system.out.print ("Method parameter types : "); 
      		for (Class class1 : guru99ParamList){ 
      			System.out.println(class1.getName()+" ");
      		}
              System.out.println();
      		
      		// Get and print exception thrown by the method 
      		Class[] guru99ExceptionList = method. getExceptionTypes(); 
      		system.out.print("Excpetion thrown by method :"); 
      		for (Class class1 : guru99ExceptionList) {
      			System.out.println (class1.getName() +" "):
      		} 
      		System.Out.println(); 
      		system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
      		
      		}
       
      	}
      }
      
      1. Δημιουργήθηκε αντικείμενο κλάσης για το Guru99MethodMetaData.class
      2. Λάβαμε όλα τα μεταδεδομένα όλων των μεθόδων σε έναν πίνακα μεθόδων
      3. Εκτύπωσε όλα τα ονόματα μεθόδων που υπάρχουν στην κλάση Guru99MethodMetaData.class
      4. Εκτυπωμένοι τύποι επιστροφής των μεθόδων στην κλάση Guru99MethodMetaData.class
      5. Εκτύπωσε όλους τους τροποποιητές πρόσβασης των μεθόδων στην κλάση Guru99MethodMetaData.class
      6. Εκτυπωμένοι τύποι παραμέτρων των μεθόδων στο Guru99MethodMetaData.class
      7. Οι εκτυπωμένες εξαιρέσεις γίνονται με μεθόδους στο Guru99MethodMetaData.class

        Λήψη μεταδεδομένων μεθόδου

      Λήψη μεταδεδομένων μεθόδου

      Παράδειγμα 4: Πώς να αποκτήσετε Μεταδεδομένα Κατασκευαστών

      Τα ακόλουθα παραδείγματα δείχνουν πώς μπορείτε να λάβετε μεταδεδομένα κατασκευαστών:

      Εδώ, δημιουργούμε μια κλάση με το όνομα Guru99Constructor.class με διαφορετικούς κατασκευαστές:

      Λάβετε Μεταδεδομένα Κατασκευαστών

      package guru;		
      
      import java.rmi.RemoteException;		
      import java.sql.SQLException;		
      
      public class Guru99Constructor {				
      
      	public Guru99Constructor(int no) throws ClassCastException ,ArithmeticException{  }							
      	public Guru99Constructor(int no, String name) throws RemoteException ,SQLException{  }							
      	public Guru99Constructor(int no, String name, String address) throws InterruptedException{  }							
      }

      Εδώ, γράφουμε μια τάξη για να λάβουμε τα μεταδεδομένα των κατασκευαστών που υπάρχουν στην κλάση Guru99Constructor.class:

      Λάβετε Μεταδεδομένα Κατασκευαστών

      package guru;
      import java.lang.reflect.Constructor; 
      public class Guru99ConstructorMetaDataTest {
      	
      	public static void main (String[] args) {
      		// Create Class object for Guru99Constructor.class 
      		Class guru99Class=Guru99Constructor.class;
      
      		// Get all the constructor information in the Constructor array
      		Constructor[] guru99ConstructorList = guru99Class.getConstructors();
      		
      		for (Constructor constructor : guru99ConstructorList) {
      			// Print all name of each constructor
      			System.out.println("Constrcutor name : "+constructor.getName());
      			
      			//Get and print access modifiers of each constructor 
      			int guru99Modifiers= constructor.getModifiers(); 
      			System.Out.printlin ("Constrctor modifier : "+Modifier.toString(guru99Modifiers));
      			
      			// Get and print parameter types 
      			Class[] guru99ParamList=constructor.getParameterTypes();
      			System.out.print ("Constrctor parameter types :"); 
      			for (Class class1 : guru99ParamList) { 
      				System.out.println(class1.getName() +" ");
      			}
      			System. out.println();
      
      			// Get and print exception thrown by constructors
      			Class[] guru99ExceptionList=constructor.getFxceptionTypes();
      			System.out.println("Exception thrown by constructors :"); 
      			for (Class class1 : guru99ExceptionList) { 
      				System.out.println(class1.getName() +" ");
      			} 
      			System.out.println();
      			System.out.println("*******************************************");
      		}
      	}
      }
      
      1. Δημιουργήθηκε αντικείμενο κλάσης για το Guru99Constructor.class
      2. Λάβαμε όλα τα μεταδεδομένα όλων των κατασκευαστών σε έναν πίνακα Κατασκευαστή
      3. Εκτύπωσε όλα τα ονόματα του κατασκευαστή που υπάρχουν στην κλάση Guru99Constructor.class
      4. Εκτύπωσε όλους τους τροποποιητές πρόσβασης των κατασκευαστών στην κατηγορία Guru99Constructor.class
      5. Εκτυπωμένοι τύποι παραμέτρων των κατασκευαστών στο Guru99Constructor.class
      6. Οι εκτυπωμένες εξαιρέσεις δημιουργούνται από τους κατασκευαστές στο Guru99Constructor.class

      Λάβετε Μεταδεδομένα Κατασκευαστών

      Λάβετε Μεταδεδομένα Κατασκευαστών

      Σύνοψη

      • Ο προγραμματισμός αντανακλάσεων σε java βοηθά στην ανάκτηση και τροποποίηση πληροφοριών σχετικά με τις κλάσεις και τα μέλη της κλάσης, όπως μεταβλητές, μεθόδους, κατασκευαστές.
      • Reflection API in Java μπορεί να υλοποιηθεί χρησιμοποιώντας κλάσεις στο πακέτο java.lang.reflect και μεθόδους της κλάσης java.lang.Class.
      • Μερικές κοινώς χρησιμοποιούμενες μέθοδοι της κλάσης java.lang.Class είναι οι getName (), getSuperclass (), getInterfaces (), getModifiers () κ.λπ.
      • Ορισμένες κλάσεις που χρησιμοποιούνται συνήθως στο πακέτο java.lang.reflect είναι το Field, Method, Constructor, Modifier κ.λπ.
      • Το Reflection API μπορεί να έχει πρόσβαση σε ιδιωτικές μεθόδους και μεταβλητές μιας κλάσης που θα μπορούσαν να αποτελέσουν απειλή για την ασφάλεια.
      • Το Reflection API είναι μια ισχυρή δυνατότητα που παρέχεται από Java, αλλά συνοδεύεται από ορισμένα γενικά έξοδα, όπως πιο αργή απόδοση, ευπάθεια ασφαλείας και πρόβλημα άδειας. Ως εκ τούτου, το API ανάκλασης θα πρέπει να αντιμετωπίζεται ως η τελευταία λύση για την εκτέλεση μιας λειτουργίας.