Reflection trong Java là gì?
Java Reflection là quá trình phân tích và sửa đổi tất cả các khả năng của một lớp trong thời gian chạy. Reflection API trong Java được sử dụng để thao tác với lớp và các thành viên của nó bao gồm các trường, phương thức, hàm tạo, v.v. trong thời gian chạy.
Một lợi thế của API phản chiếu trong Java là, nó cũng có thể thao túng các thành viên riêng tư của lớp.
Gói java.lang.reflect cung cấp nhiều lớp để triển khai java phản chiếu. Các lớp java.lang.Class được sử dụng để thu thập siêu dữ liệu hoàn chỉnh của một lớp cụ thể.
Trong hướng dẫn này, bạn sẽ học-
- Phản ánh là gì
- Lớp trong Gói java.lang.reflect
- Các phương thức được sử dụng trong java.lang.Class
- Cách nhận thông tin đầy đủ về một lớp học
- Ví dụ 1: Cách lấy Siêu dữ liệu của Lớp
- Ví dụ 2: Cách lấy Siêu dữ liệu của Biến
- Ví dụ 3: Cách lấy Siêu dữ liệu của Phương thức
- Ví dụ 4: Cách lấy Siêu dữ liệu của Trình tạo
Lớp trong Gói java.lang.reflect
Sau đây là danh sách các lớp Java khác nhau trong java.lang.package để thực hiện phản xạ-
- Trường : Lớp này được sử dụng để thu thập thông tin khai báo như kiểu dữ liệu, công cụ sửa đổi truy cập, tên và giá trị của một biến.
- Phương thức : Lớp này được sử dụng để thu thập thông tin khai báo như công cụ sửa đổi truy cập, kiểu trả về, tên, các kiểu tham số và kiểu ngoại lệ của một phương thức.
- Constructor : Lớp này được sử dụng để thu thập thông tin khai báo như công cụ sửa đổi truy cập, tên và các kiểu tham số của một phương thức khởi tạo.
- Công cụ sửa đổi : Lớp này được sử dụng để thu thập thông tin về một công cụ sửa đổi truy cập cụ thể.
Các phương thức được sử dụng trong java.lang.Class
- Public String getName () : Trả về tên của lớp.
- public Class getSuperclass () : Trả về tham chiếu siêu lớp
- Public Class [] getInterfaces () : Trả về một mảng các giao diện được thực hiện bởi lớp được chỉ định
- Công khai trong getModifier (): Trả về một giá trị số nguyên đại diện cho các sửa đổi của lớp được chỉ định cần được chuyển làm tham số cho phương thức " public static String toString (int i)", phương thức này trả về chỉ định truy cập cho lớp đã cho.
Cách nhận thông tin đầy đủ về một lớp học
Để lấy thông tin về các biến, phương thức và hàm tạo của một lớp, chúng ta cần tạo một đối tượng của lớp.public class Guru99ClassObjectCreation {public static void main (String[] args) throws ClassNotFoundException {//1 - By using Class.forname() methodClass c1 = Class.forName("Guru99ClassObjectCreation");//2- By using getClass() methodGuru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();Class c2 = guru99Obj.getClass();//3- By using .classClass c3= Guru99ClassObjectCreation.class;}}
Ví dụ 1: Cách lấy Siêu dữ liệu của Lớp
Ví dụ sau cho thấy cách lấy siêu dữ liệu như: Tên lớp, tên siêu lớp, các giao diện được triển khai và các bổ ngữ truy cập của một lớp.
Chúng tôi sẽ nhận được siêu dữ liệu của lớp bên dưới có tên Guru99Base.class:
import java.io.Serializable;public abstract class Guru99Base implements Serializable,Cloneable {}
- Tên của lớp là: Guru99Base
- Các công cụ sửa đổi quyền truy cập của nó là: công khai và trừu tượng
- Nó đã thực hiện các giao diện: Có thể nối tiếp và có thể sao chép
- Vì nó không mở rộng bất kỳ lớp nào một cách rõ ràng, nên siêu lớp của nó là: java.lang.Object
import java.lang.reflect.Modifier;public class Guru99GetclassMetaData {public static void main (String [] args) throws ClassNotFoundException {// Create Class object for Guru99Base.classClassguru99ClassObj = Guru99Base.class;// Print name of the classsystem.out.println("Name of the class is : " +guru99ClassObj.getName());// Print Super class namesystem.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() methodclass[] guru99InterfaceList = guru99classObj.getInterfaces();// Print the implemented interfaces using foreach loopsystem.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 classint guru99AccessModifier= guru99classObj.getModifiers();// Print the access modifiersSystem.Out.println("Access modifiers of the class are : " +Modifier.tostring(guru99AccessModifier));}}
- in tên của lớp bằng phương thức getName
- In tên của siêu lớp bằng phương thức getSuperClass (). GetName ()
- In tên của các giao diện đã triển khai
- In các công cụ sửa đổi quyền truy cập được sử dụng bởi lớp
Ví dụ 2: Cách lấy Siêu dữ liệu của Biến
Các ví dụ sau đây cho thấy cách lấy siêu dữ liệu của biến:
Ở đây, chúng tôi đang tạo một lớp có tên Guru99VariableMetaData .class với một số biến:
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";}Các bước để lấy siêu dữ liệu về các biến trong lớp trên:
- Tạo đối tượng lớp của lớp trên tức là Guru99VariableMetaData.class như bên dưới:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();Class guru99ClassObjVar = guru99ClassVar.getClass();
- Lấy siêu dữ liệu ở dạng mảng trường bằng cách sử dụng các phương thức getFields () hoặc getDeclaredFields () như bên dưới:
Field[] guru99Field1= guru99ClassObjVar .getFields();Field[] guru99Fiel2= guru99ClassObjVar .getDeclaredFields();
Phương thức getFields () trả về siêu dữ liệu của biến công khai từ lớp được chỉ định cũng như từ siêu lớp của nó.
Phương thức getDeclaredFields () trả về siêu dữ liệu của tất cả các biến chỉ từ lớp được chỉ định.
- Lấy tên của các biến bằng phương thức "public String getName ()".
- Lấy kiểu dữ liệu của các biến bằng phương thức "public Class getType ()".
- Lấy giá trị của biến bằng phương thức "public xxx get (Field)".
Ở đây, xxx có thể là một byte hoặc ngắn của bất kỳ loại giá trị nào mà chúng tôi muốn tìm nạp.
- Nhận công cụ sửa đổi quyền truy cập của các biến bằng cách sử dụng các phương thức getModifier () và Modifier.toString (int i).
Ở đây, chúng tôi đang viết một lớp để lấy siêu dữ liệu của các biến có trong lớp 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.classGuru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();Class guru99ClassObjVar = guru99ClassVar.getClass();// Get the metadata of all the fields of the class Guru99VariableMetaDataField[] guru99Field1= guru99ClassObjVar.getDeclaredFields();// Print name, datatypes, access modifiers and values of the varibales of the specified classfor(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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;}}}
- Đã tạo đối tượng lớp cho Guru99VariableMetaData.class
- Có tất cả siêu dữ liệu của các biến trong một mảng Trường
- Đã in tất cả các tên biến trong lớp Guru99VariableMetaData.class
- Đã in tất cả các kiểu dữ liệu của các biến trong lớp Guru99VariableMetaData.class
- Đã in tất cả các công cụ sửa đổi quyền truy cập của các biến trong lớp Guru99VariableMetaData.class
- Đã in giá trị của tất cả các biến trong Đã in tất cả các kiểu dữ liệu của các biến trong lớp Guru99VariableMetaData.class
- Tạo đối tượng lớp của lớp trên tức là Guru99MethodMetaData.class như bên dưới:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData ();Class guru99ClassObjVar = guru99ClassVar.getClass();
- Nhận thông tin phương thức trong một mảng Phương thức bằng cách sử dụng phương thức getMethods () và getDeclaredMethods () như bên dưới:
Method[] guru99 Method 1= guru99ClassObjVar .get Methods();Method [] guru99 Method 2= guru99ClassObjVar .getDeclared Method s();
Phương thức getMethods () trả về siêu dữ liệu của các phương thức công khai từ lớp được chỉ định cũng như từ siêu lớp của nó.
Phương thức getDeclaredMethods () trả về siêu dữ liệu của tất cả các phương thức chỉ từ lớp được chỉ định.
- Lấy tên của phương thức bằng phương thức getName () .
- Lấy kiểu trả về của phương thức bằng phương thức getReturnType () .
- Nhận công cụ sửa đổi quyền truy cập của các phương thức bằng các phương thức getModifier () và Modifiers.toString (int i) .
- Nhận các kiểu tham số phương thức bằng cách sử dụng phương thức getParameterTypes () trả về một mảng lớp.
- Lấy ngoại lệ ném ra bằng cách sử dụng phương thức getExceptionTypes () trả về một mảng lớp.
- Đã tạo đối tượng lớp cho Guru99MethodMetaData.class
- Có tất cả siêu dữ liệu của tất cả các phương thức trong một mảng Phương thức
- Đã in tất cả các tên phương thức có trong lớp Guru99MethodMetaData.class
- Các kiểu trả về được in của các phương thức trong lớp Guru99MethodMetaData.class
- Đã in tất cả các sửa đổi truy cập của các phương thức trong lớp Guru99MethodMetaData.class
- Các kiểu tham số được in của các phương thức trong Guru99MethodMetaData.class
- Các ngoại lệ đã in được ném bởi các phương thức trong Guru99MethodMetaData.class
- Đã tạo đối tượng lớp cho Guru99Constructor.class
- Nhận tất cả siêu dữ liệu của tất cả các hàm tạo trong một mảng Hàm tạo
- Đã in tất cả các tên của hàm tạo có trong lớp Guru99Constructor.class
- Đã in tất cả các sửa đổi truy cập của các hàm tạo trong lớp Guru99Constructor.class
- Các kiểu tham số được in của các hàm tạo trong Guru99Constructor.class
- Các ngoại lệ đã in được ném bởi các hàm tạo trong Guru99Constructor.class
- Lập trình phản chiếu trong java giúp truy xuất và sửa đổi thông tin về Lớp và các thành viên Lớp như biến, phương thức, hàm tạo.
- Reflection API trong Java có thể được triển khai bằng cách sử dụng các lớp trong gói java.lang.reflect và các phương thức của lớp java.lang.Class.
- Một số phương thức thường được sử dụng của lớp java.lang.Class là getName (), getSuperclass (), getInterfaces (), getModifier (), v.v.
- Một số lớp thường được sử dụng trong gói java.lang.reflect là Field, Method, Constructor, Modifier, v.v.
- Reflection API có thể truy cập các phương thức và biến riêng tư của một lớp có thể là một mối đe dọa bảo mật.
- Reflection API là một khả năng mạnh mẽ được cung cấp bởi Java, nhưng nó đi kèm với một số chi phí như hiệu suất chậm hơn, lỗ hổng bảo mật và vấn đề về quyền. Do đó, API phản chiếu nên được coi là phương sách cuối cùng để thực hiện một hoạt động.
Ví dụ 3: Cách lấy Siêu dữ liệu của Phương thức
Các ví dụ sau đây cho thấy cách lấy siêu dữ liệu của một phương thức:
Ở đây, chúng tôi đang tạo một lớp có tên Guru99MethodMetaData .class với một số phương thức
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");}}
Các bước để lấy siêu dữ liệu về các phương thức trong lớp trên:
Ở đây, chúng tôi đang viết một lớp để lấy siêu dữ liệu của các phương thức có trong lớp 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.classclass 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 namesSystem.out.println("Name of the method : "+method.getName());// Print return type of the methodsSystem.out.println("Return type of the method : "+method.getReturnType());//Get the access modifier list and printint guru99ModifierList = method.getModifiers();System.Out.printlin ("Method access modifiers : "+Modifier.toString(guru99ModifierList));// Get and print parameters of the methodsClass[] 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 methodClass[] 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");}}}
Ví dụ 4: Cách lấy Siêu dữ liệu của Trình tạo
Các ví dụ sau đây cho thấy cách lấy siêu dữ liệu của các hàm tạo:
Ở đây, chúng tôi đang tạo một lớp có tên Guru99Constructor.class với các hàm tạo khác nhau:
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{ }}
Ở đây, chúng ta đang viết một lớp để lấy siêu dữ liệu của các hàm tạo có trong lớp Guru99Constructor.class:
package guru;import java.lang.reflect.Constructor;public class Guru99ConstructorMetaDataTest {public static void main (String[] args) {// Create Class object for Guru99Constructor.classClass guru99Class=Guru99Constructor.class;// Get all the constructor information in the Constructor arrayConstructor[] guru99ConstructorList = guru99Class.getConstructors();for (Constructor constructor : guru99ConstructorList) {// Print all name of each constructorSystem.out.println("Constrcutor name : "+constructor.getName());//Get and print access modifiers of each constructorint guru99Modifiers= constructor.getModifiers();System.Out.printlin ("Constrctor modifier : "+Modifier.toString(guru99Modifiers));// Get and print parameter typesClass[] 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 constructorsClass[] 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("*******************************************");}}}
Tóm lược: