亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java反射中的類有哪些

發布時間:2022-01-30 10:25:16 來源:億速云 閱讀:157 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Java反射中的類有哪些”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java反射中的類有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

    一、什么是反射

    java.lang包提供java語言程序設計的基礎類,在lang包下存在一個子包:reflect,與反射相關的APIs均在此處;

    官方對reflect包的介紹如下:

    Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.
    The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

    java.lang.reflect官方介紹

    簡單來說,反射機制就像類對照平靜的湖面,湖面映射出類的字段、方法、構造函數等信息;反射機制不僅可以看到類信息,還能針對字段、方法等做出相應的操作。

    二、準備測試:實體類的創建

    為方便解釋說明,首先創建一個實體類,用于測試使用

    package cn.byuan.entity;
    
    /**
     * 學生實體類
     *
     * @author byuan
     * @date 2022-01-25
     */
    public class Student {
    
        /**
         * 學生學號, 公共變量, 默認值: defaultStudentNo
         * */
        public String studentNo = "defaultStudentNo";
    
        /**
         * 學生姓名, 公共變量, 默認值: defaultStudentName
         * */
        public String studentName = "defaultStudentName";
    
        /**
         * 學生性別, 私有變量, 默認值: defaultStudentSex
         * */
        private String studentSex = "defaultStudentSex";
    
        /**
         * 學生年齡, 私有變量, 默認值: 0
         * */
        private Integer studentAge = 0;
    
        /**
         * 公有無參構造方法
         * */
        public Student() {
    
        }
    
        /**
         * 公有滿參構造方法
         * */
        public Student(String studentNo, String studentName, String studentSex, Integer studentAge) {
            this.studentNo = studentNo;
            this.studentName = studentName;
            this.studentSex = studentSex;
            this.studentAge = studentAge;
        }
    
        /**
         * 私有構造方法
         * */
        private Student(String studentSex, Integer studentAge) {
            this.studentSex = studentSex;
            this.studentAge = studentAge;
        }
    
        /**
         * get/set 方法
         * */
        public String getStudentNo() {
            return studentNo;
        }
    
        public Student setStudentNo(String studentNo) {
            this.studentNo = studentNo;
            return this;
        }
    
        public String getStudentName() {
            return studentName;
        }
    
        public Student setStudentName(String studentName) {
            this.studentName = studentName;
            return this;
        }
    
        public String getStudentSex() {
            return studentSex;
        }
    
        public Student setStudentSex(String studentSex) {
            this.studentSex = studentSex;
            return this;
        }
    
        public Integer getStudentAge() {
            return studentAge;
        }
    
        public Student setStudentAge(Integer studentAge) {
            this.studentAge = studentAge;
            return this;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "studentNo = " + this.studentNo + ", " +
                    "studentName = " + this.studentName + ", " +
                    "studentSex = " + this.studentSex + ", " +
                    "studentAge = " + this.studentAge +"}";
        }
    
        /**
         * 學生類說話方法
         * */
        private String speak(String message) {
            return this.studentName + " : " + message;
        }
    
    }

    三、反射中的幾個重要類及方法

    在了解反射前,先來梳理下一個類(Class)本身中包含了哪些內容。

    • 字段,字段又由修飾符、字段類型、字段名稱、對應值等部分組成

    • 構造方法,構造方法可簡單分為無參與有參兩大類

    • 非構造方法,又稱普通方法,方法由修飾符、返回值類型、方法名、形參表、方法體等部分構成

    本文所論述的反射中幾個重要類及其對應方法正基于以上內容

    (一)反射中的重要類之Class

    Class類代表了類本身,類本身包含字段,構造方法,非構造方法等內容,因此使用反射的第一步就是獲取對象所對應的Class類。

    僅就使用反射而言,我們需著重了解Class類的獲取方式,下面給出實例

    1. Class類測試實例

    package cn.byuan.example;
    import cn.byuan.entity.Student;
    /**
     * 獲取 Class 的幾種方式
     *
     * @author byuan
     * @date 2022-01-25
     */
    public class GetClassExample {
        public static void main(String[] args) throws ClassNotFoundException {
            // 獲取 class 方式一: 通過類的全路徑字符串獲取 Class 對象
            Class getClassExample1 = Class.forName("cn.byuan.entity.Student");
            // 獲取 class 方式二: 通過類名直接獲取
            Class getClassExample2 = Student.class;
            // 獲取 class 方式三: 通過已創建的對象獲取對應 Class
            Student student1 = new Student();
            Class getClassExample3 = student1.getClass();
        }
    }

    (二)反射中的重要類之Field

    Field類是對類中屬性的描述,借助Class與Field的配合,我們可以了解類中有哪些字段,并做出相應處理;

    1. Field類的獲取與常用方法

    Class類為我們提供了兩個方法用以獲取Field類:

    • getDeclaredFields():獲取所有聲明的字段(包括公有字段和私有字段)

    • getFields():僅可獲取公有字段

    Field類代表了類中的屬性字段,常用類中屬性字段可籠統分為兩種,公有字段(public)與私有字段(private);

    每個字段又具有四個屬性:修飾符,字段類型,字段名稱,對應值;Field也自然提供了對應方法對這四種屬性進行獲取:

    • getModifiers():獲取字段修飾符相加值,想要獲取明確標識需要通過Modifier常量的toString方法對相加值進行解碼

    • getType():獲取字段類型

    • getName():獲取字段名稱

    • get(Object):獲取字段對應值

    下面給出實例

    2. Field類測試實例

    package cn.byuan.example;
    
    import cn.byuan.entity.Student;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    
    /**
     * 獲取類字段的幾種方式
     *
     * @author byuan
     * @date 2021-01-25
     */
    public class GetFieldExample {
        public static void main(String[] args) throws IllegalAccessException {
            Class studentClass = Student.class;
            // 獲取類字段的兩個方法: getDeclaredFields, getFields
            // 1. getDeclaredFields: 獲取所有聲明的字段(包括公有字段和私有字段)
            Field[] declaredFieldArray = studentClass.getDeclaredFields();
            printFieldInformation(declaredFieldArray);
            // 2. getFields: 僅可獲取公有字段
            Field[] fieldArray = studentClass.getFields();
            printFieldInformation(fieldArray);
            // 獲取字段對應值
            Student student = new Student()
                    .setStudentSex("女")
                    .setStudentAge(18);
            printFieldValue(student);
        }
    
        /**
         * 打印類字段信息
         *
         * @param fieldArray 類字段對象列表
         * */
        public static void printFieldInformation(Field[] fieldArray) {
            for (Field fieldPart : fieldArray) {
                System.out.println("直接打印類字段對象: " + fieldPart);
                // 獲取字段修飾符
                String fieldModifier = Modifier.toString(fieldPart.getModifiers());
                // 獲取字段類型
                String fieldType = fieldPart.getType().getName();
                // 獲取字段名稱
                String fieldName = fieldPart.getName();
                System.out.println(fieldModifier + " " + fieldType + " " + fieldName);
            }
            System.out.println();
        }
    
        /**
         * 打印類字段屬性
         *
         * @param t 泛型對象
         * */
        private static <T> void printFieldValue(T t) throws IllegalAccessException {
            Field[] fieldValueArray = t
                    .getClass()
                    .getDeclaredFields();
            for (Field fieldValuePart : fieldValueArray) {
                // 對于有可能存在的 private 字段取消語言訪問檢查
                fieldValuePart.setAccessible(true);
                // 字段名稱
                String filedName = fieldValuePart.getName();
                // 字段對應值
                String fieldValue = fieldValuePart.get(t).toString();
                System.out.println(filedName + " = " + fieldValue);
            }
        }
    }

    運行截圖

    Java反射中的類有哪些

    (三)反射中的重要類之Constructor

    Constructor代表了某個類的構造方法,是用來管理所有的構造函數的類

    1. Constructor類的獲取與常用方法

    Class類為我們提供了兩個方法用以獲取Constructor類:

    1. getDeclaredConstructors():獲取所有構造方法

    2. getConstructors():僅可獲取公有構造方法

    對于構造器,可簡單將其分為兩大類,無參構造器與帶參構造器,構造器也是方法的一種,因此對于任意一構造器都由修飾符,方法名,形參表,方法體四部分組成;Constructor自然也為其組成部分提供了對應方法:

    1. 與字段類似,Constructors同樣提供了getModifiers()方法:獲取構造器修飾符相加值,想要獲取明確標識需要通過Modifier常量的toString方法進行解碼

    2. getName():獲取構造器名稱

    3. getParameterTypes():獲取構造器參數列表

    下面給出實例

    2. Constructor類測試實例

    package cn.byuan.example;
    import cn.byuan.entity.Student;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Modifier;
    
    /**
     * 獲取構造方法的幾種方式
     *
     * @author byuan
     * @date 2022-01-25
     */
    public class GetConstructorsExample {
        public static void main(String[] args) {
            Class studentClass = Student.class;
            // 獲取類構造器的兩個方法: getDeclaredConstructors, getConstructors
            // 1. getDeclaredConstructors: 獲取所有構造方法
            Constructor[] declaredConstructorArray = studentClass.getDeclaredConstructors();
            printConstructorInformation(declaredConstructorArray);
            // 2. getConstructors, 僅可獲取公有構造方法
            Constructor[] constructorArray = studentClass.getConstructors();
            printConstructorInformation(constructorArray);
        }
    
        /**
         * 打印構造器信息
         *
         * @param constructorArray 構造器對象列表
         * */
        public static void printConstructorInformation(Constructor[] constructorArray) {
            for (Constructor constructorPart : constructorArray) {
                System.out.println("直接打印構造器對象: " + constructorPart);
                // 獲取構造器修飾符
                String constructorModifier = Modifier.toString(constructorPart.getModifiers());
                // 獲取構造器名稱
                String constructorName = constructorPart.getName();
                // 獲取構造器參數列表
                Class[] constructorParameterArray = constructorPart.getParameterTypes();
                // 打印構造器參數列表
                System.out.print(constructorModifier + " " + constructorName + "(");
                for (Class constructorParameterPart : constructorParameterArray) {
                    System.out.print(constructorParameterPart.getName() + " ");
                }
                System.out.println(")");
            }
            System.out.println();
        }
    }

    運行截圖

    Java反射中的類有哪些

    3. 利用Constructor類實例化對象

    一般而言,我們關心的不只是獲取到對象構造器的具體信息,更重要的是如何利用反射實例化對象,針對對象實例化,Constructor提供了兩種類型的方法:

    1. getConstructor(Class<?>... parameterTypes):獲取指定形參表的構造方法,可借助其獲取無參/指定參數的構造方法;

    2. newInstance(Object ... initargs):通過形參表傳遞實例化對象參數,與getConstructor配合使用;

    注意:Class也存在newInstance()方法,但僅能用來調用類的無參構造器

    4. Constructor實例化對象測試實例

    package cn.byuan.example;
    import cn.byuan.entity.Student;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    /**
     * 構造器調用實例
     *
     * @author byuan
     * @date 2022-01-26
     */
    public class ConstructorsInvokeExample {
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class studentClass = Student.class;
            // Class 類的 newInstance 方法
            studentClass.newInstance();
            // 1. 調用公有無參構造器
            Object object1 = studentClass
                    .getConstructor()
                    .newInstance();
            System.out.println(object1.getClass());
            // 2. 調用公有滿參構造器
            Constructor studentConstructorFull = studentClass
                    .getConstructor(String.class, String.class, String.class, Integer.class);
            Object object2 = studentConstructorFull
                    .newInstance("2022001", "趙一", "男", 18);
            System.out.println(object2);
            // 3. 調用私有構造器
            Constructor studentConstructorPrivate = studentClass
                    .getDeclaredConstructor(String.class, Integer.class);
            // 私有構造器需將 accessible 設置為 true, 取消語言訪問檢查
            studentConstructorPrivate.setAccessible(true);
            Object object3 = studentConstructorPrivate
                    .newInstance("女", 19);
            System.out.println(object3);
        }
    }

    運行截圖

    Java反射中的類有哪些

    (四)反射中的重要類之Method

    Method類描述了類的方法信息

    1. Method類的獲取與常用方法

    Class類為我們提供了兩個方法用以獲取Method類:

    1. getDeclaredMethods():獲取所有非構造方法

    2. getMethods():僅可獲取公有非構造方法

    對于任意方法都可分為修飾符,方法名,形參表,方法體四部分;Method為其組成部分提供了對應方法:

    1. getModifiers():獲取方法修飾符相加值,想要獲取明確標識需要通過Modifier常量的toString方法進行解碼

    2. getName():獲取方法名稱

    3. getParameterTypes():獲取方法形參表

    2. Method類測試實例

    package cn.byuan.example;
    import cn.byuan.entity.Student;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    /**
     * 獲取非構造方法的幾種方式
     *
     * @author byuan
     * @date 2022-01-26
     */
    public class GetMethodExample {
        public static void main(String[] args) {
            Class studentClass = Student.class;
            // 獲取非構造方法的兩個方法: getDeclaredMethods, getMethods
            // 1. getDeclaredMethods: 獲取所有非構造方法
            Method[] declaredMethodArray = studentClass.getDeclaredMethods();
            printMethodInformation(declaredMethodArray);
            // 2. getMethods, 僅可獲取公有非構造方法
            Method[] methodArray = studentClass.getMethods();
            printMethodInformation(methodArray);
        }
    
        /**
         * 打印非構造器方法信息
         *
         * @param methodArray 構造器對象列表
         * */
        public static void printMethodInformation(Method[] methodArray) {
            for (Method methodPart : methodArray) {
                System.out.println("直接打印非構造方法對象: " + methodArray);
                // 獲取非構造器方法修飾符
                String methodModifier = Modifier.toString(methodPart.getModifiers());
                // 獲取非構造器方法名稱
                String methodName = methodPart.getName();
                String methodReturnType = methodPart.getReturnType().getName();
                // 獲取非構造方法參數列表
                Class[] constructorParameterArray = methodPart.getParameterTypes();
                // 打印非構造方法參數列表
                System.out.print(methodModifier + " " + methodReturnType + " " + methodName + "(");
                for (Class methodParameterPart : constructorParameterArray) {
                    System.out.print(methodParameterPart.getName() + " ");
                }
                System.out.println(")");
            }
            System.out.println();
        }
    }

    運行截圖

    Java反射中的類有哪些

    3. 利用Method調用非構造方法

    與利用Constructor實例化對象相似,Method同樣需要兩個方法用以調用非構造方法

    1. getDeclaredMethod(方法名, 形參表數組): 獲取所有構造方法

    2. invoke(對象實例, 參數數組):方法調用

    4. Method調用非構造方法測試實例

    package cn.byuan.example;
    import cn.byuan.entity.Student;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * 非構造器方法調用實例
     *
     * @author byuan
     * @date 2022-01-26
     */
    public class MethodInvokeExample {
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
            Class studentClass = Student.class;
            // 對于私有的非構造方法, 需要使用 getDeclaredMethod 進行獲取
            // getDeclaredMethod(方法名, 形參表數組)
            Method studentSpeakMethod = studentClass.getDeclaredMethod("speak", new Class[]{String.class});
            // 取消語言訪問檢查
            studentSpeakMethod.setAccessible(true);
            // invoke(對象實例, 參數數組)
            Object object = studentSpeakMethod.invoke(studentClass.newInstance(), "Hello, world");
            System.out.println(object);
        }
    }

    運行截圖

    Java反射中的類有哪些

    四、綜合實戰:利用反射機制編寫對象拷貝工具類

    在實際項目中,我們經常會遇到POJO與VO等類型對象進行相互轉換的情況,如果直接進行轉換則會使用大量的樣板代碼,為消除這樣的代碼,我們可以寫一個簡單的對象拷貝工具類進行解決;

    (一)業務分析

    通過反射獲取源對象Field數組,并利用Field類提供的set/get方法實現同名屬性的拷貝;

    (二)實體類準備

    創建Student類

    package cn.byuan.entity;
    
    /**
     * 學生實體類
     *
     * @author byuan
     * @date 2022-01-25
     */
    public class Student {
    
        /**
         * 學生學號, 公共變量, 默認值: defaultStudentNo
         * */
        public String studentNo = "defaultStudentNo";
    
        /**
         * 學生姓名, 公共變量, 默認值: defaultStudentName
         * */
        public String studentName = "defaultStudentName";
    
        /**
         * 學生性別, 私有變量, 默認值: defaultStudentSex
         * */
        private String studentSex = "defaultStudentSex";
    
        /**
         * 學生年齡, 私有變量, 默認值: 0
         * */
        private Integer studentAge = 0;
    
        /**
         * 公有無參構造方法
         * */
        public Student() {
    
        }
    
        /**
         * 公有滿參構造方法
         * */
        public Student(String studentNo, String studentName, String studentSex, Integer studentAge) {
            this.studentNo = studentNo;
            this.studentName = studentName;
            this.studentSex = studentSex;
            this.studentAge = studentAge;
        }
    
        /**
         * 私有構造方法
         * */
        private Student(String studentSex, Integer studentAge) {
            this.studentSex = studentSex;
            this.studentAge = studentAge;
        }
    
        public String getStudentNo() {
            return studentNo;
        }
    
        public Student setStudentNo(String studentNo) {
            this.studentNo = studentNo;
            return this;
        }
    
        public String getStudentName() {
            return studentName;
        }
    
        public Student setStudentName(String studentName) {
            this.studentName = studentName;
            return this;
        }
    
        public String getStudentSex() {
            return studentSex;
        }
    
        public Student setStudentSex(String studentSex) {
            this.studentSex = studentSex;
            return this;
        }
    
        public Integer getStudentAge() {
            return studentAge;
        }
    
        public Student setStudentAge(Integer studentAge) {
            this.studentAge = studentAge;
            return this;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "studentNo = " + this.studentNo + ", " +
                    "studentName = " + this.studentName + ", " +
                    "studentSex = " + this.studentSex + ", " +
                    "studentAge = " + this.studentAge +"}";
        }
    
        /**
         * 學生類說話方法
         * */
        private String speak(String message) {
            return this.studentName + " : " + message;
        }
    }

    創建StudentOut類

    package cn.byuan.api.out;
    
    import cn.byuan.entity.Student;
    
    /**
     * 學生類出參
     *
     * @author byuan
     * @date 2022-01-26
     */
    public class StudentOut {
        /**
         * 學生學號, 公共變量
         * */
        private String studentNo;
    
        /**
         * 學生姓名, 公共變量
         * */
        private String studentName;
    
        /**
         * 學生性別, 私有變量
         * */
        private String studentSex;
    
        /**
         * 學生年齡, 私有變量
         * */
        private Integer studentAge;
    
        public String getStudentNo() {
            return studentNo;
        }
    
        public StudentOut setStudentNo(String studentNo) {
            this.studentNo = studentNo;
            return this;
        }
    
        public String getStudentName() {
            return studentName;
        }
    
        public StudentOut setStudentName(String studentName) {
            this.studentName = studentName;
            return this;
        }
    
        public String getStudentSex() {
            return studentSex;
        }
    
        public StudentOut setStudentSex(String studentSex) {
            this.studentSex = studentSex;
            return this;
        }
    
        public Integer getStudentAge() {
            return studentAge;
        }
    
        public StudentOut setStudentAge(Integer studentAge) {
            this.studentAge = studentAge;
            return this;
        }
    
        @Override
        public String toString() {
            return "StudentOut{" +
                    "studentNo = " + this.studentNo + ", " +
                    "studentName = " + this.studentName + ", " +
                    "studentSex = " + this.studentSex + ", " +
                    "studentAge = " + this.studentAge +"}";
        }
    }

    (三)工具類編寫

    package cn.byuan.util;
    import cn.byuan.api.out.StudentOut;
    import cn.byuan.entity.Student;
    import java.lang.reflect.Field;
    
    /**
     * 對象屬性拷貝工具類
     *
     * @author byuan
     * @date 2022-01-26
     */
    public class BeanUtil {
        /**
         * 對象拷貝工具
         *
         * @param sourceObject 源對象
         * @param destClass 目的對象對應 Class
         *
         * @return 拷貝完畢后對象
         * */
        public static <T> T copyObject(Object sourceObject, Class<T> destClass) {
            if (sourceObject == null) {
                return null;
            }
    
            try {
    
                T destObject = destClass.newInstance();
    
                copyField(sourceObject, destObject);
    
                return destObject;
    
            } catch (InstantiationException e) {
                e.printStackTrace();
                
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 對象屬性拷貝工具
         *
         * @param sourceObject 源對象
         * @param destObject 目的對象
         * */
        private static void copyField(Object sourceObject, Object destObject) {
            if (sourceObject == null || destObject == null) {
                return;
            }
    
            // 獲取源對象所有字段
            Field[] sourceFieldArray = sourceObject.getClass().getDeclaredFields();
            for (Field sourceFieldPart : sourceFieldArray) {
                // 取消語言訪問檢查
                sourceFieldPart.setAccessible(true);
                String sourceFieldName = sourceFieldPart.getName();
                try {
                    // 根據屬性名稱獲取目標對象對應類字段
                    Field destField = destObject
                            .getClass()
                            .getDeclaredField(sourceFieldName);
                    destField.setAccessible(true);
                    destField.set(destObject, sourceFieldPart.get(sourceObject));
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
        public static void main(String[] args) {
            Student student = new Student("2022001", "趙一", "男", 18);
            StudentOut studentOut = copyObject(student, StudentOut.class);
            System.out.println(studentOut);
        }
    }

    運行截圖

    Java反射中的類有哪些

    讀到這里,這篇“Java反射中的類有哪些”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    青田县| 许昌县| 斗六市| 云南省| 漾濞| 西昌市| 大竹县| 习水县| 綦江县| 利川市| 抚松县| 尖扎县| 沁阳市| 孟连| 溧阳市| 广安市| 连城县| 家居| 青田县| 黑水县| 沙田区| 宁夏| 广德县| 醴陵市| 江门市| 亚东县| 东光县| 红桥区| 达尔| 临沧市| 同德县| 云浮市| 响水县| 三门县| 泊头市| 县级市| 呼和浩特市| 阳谷县| 正镶白旗| 刚察县| 石狮市|