溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java反射機(jī)制怎么使用

發(fā)布時(shí)間:2022-06-06 10:06:03 來源:億速云 閱讀:96 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下Java反射機(jī)制怎么使用的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    反射的概述

    JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象.

    獲取Class對(duì)象的三種方式

    第一種方式:

    通過調(diào)用java.lang.Class類下的靜態(tài)方法:static Class forName(String className)

    注意:

    • 參數(shù)是一個(gè)帶有包名的完整類名(同目錄下的可以只寫類名)。

    • 拋出編譯時(shí)異常:ClassNotFountException。

    • 該方法會(huì)導(dǎo)致相應(yīng)的類被類加載。

    代碼如下:

    public class MyClass {
        static{
            System.out.println("靜態(tài)代碼塊執(zhí)行!");
        }
    }
    class Test{
    	Class c = Class.forName("MyClass");
    }

    編譯結(jié)果:

    Java反射機(jī)制怎么使用

    第二種方式:

    Object類下有個(gè)方法: public final Class getClass() ----- 返回此對(duì)象的Class。

    代碼如下:

    Date d = new Date();
    Class c2 = d.getClass();

    第三種方式:

    Java種任何一種類型,包括基本數(shù)據(jù)類型,都有class靜態(tài)屬性,直接通過 類名.class,就可以返回相應(yīng)的Class類。

    代碼如下:

    Class c = Date.class;

    通過反射機(jī)制獲取類的屬性

    相關(guān)方法:

    public Field[] getFields() ------- java.lang.Class中的方法,將類中public修飾的屬性以數(shù)組的形式返回

    public Field[] getDeclaredFields() ------ java.lang.Class中的方法,將類中所有的屬性以數(shù)組的形式返回

    public Class getType() ------ java.lang.reflect.Field中的方法,獲取屬性的類型并返回

    public int getModifiers() ----- java.lang.reflect.Field中的方法,獲取屬性的修飾符,并以整數(shù)編碼的形式返回(一個(gè)整數(shù)編碼可能代表多個(gè)修飾符)

    static String toString(int mod) ------ java.lang.reflect.Modifier中的靜態(tài)方法,傳入修飾符的整數(shù)編碼,以字符串的形式將修飾符返回

    代碼如下:

    public class ReflectTest05 {
        public static void main(String[] args) throws Exception{
            Class c = Class.forName("java.lang.String");
            StringBuffer s = new StringBuffer();
            s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "{\n");
            Field[] fields = c.getDeclaredFields();
            for(Field f:fields){
                s.append("\t" + Modifier.toString(f.getModifiers()) + " "+ f.getType().getName()+ " " +f.getName()+"\n");
            }
            s.append("}");
            System.out.println(s);
        }
    }

    編譯結(jié)果如下:

    Java反射機(jī)制怎么使用

    通過反射機(jī)制訪問Java對(duì)象的屬性

    創(chuàng)建一個(gè)User類,如下:

    public class User {
        //四個(gè)Field對(duì)象,分別采用四種不同的訪問權(quán)限修飾符
        public int no;
        private String name;
        protected  int age;
        boolean sex;
    }

    代碼如下:

    public class ReflectTest06 {
        public static void main(String[] args) throws Exception{
            Class c = Class.forName("User");
            //通過反射實(shí)例化User類
            Object user = c.newInstance();
            //設(shè)置User對(duì)象的no
            Field field = c.getDeclaredField("no");
            field.set(user,12);
            //獲得User對(duì)象的no
            System.out.println(field.get(user));
            //設(shè)置User對(duì)象的name,需要打破封裝,因?yàn)閚ame屬性是私有屬性,不能直接設(shè)置
            Field field1 = c.getDeclaredField("name");
            field1.setAccessible(true);
            field1.set(user,"Joke");
            System.out.println(field1.get(user));
        }
    }

    反射機(jī)制與屬性配置文件的配合使用

    資源綁定器

    java.util包下提供了一個(gè)資源綁定器,便于獲取屬性配置文件中的內(nèi)容。

    使用以下這種方式的時(shí)候,屬性配置文件xxx.properties必須放到類路徑下。

    代碼如下:

    public class ResourceBundleTest01 {
        public static void main(String[] args) {
            //資源綁定器,只能綁定xxx.properties文件,并且這個(gè)文件必須在類路徑下,文件擴(kuò)展名也必須是properties
            //并且在寫路徑時(shí),路徑后面的擴(kuò)展名不能寫
            ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
            String className = bundle.getString("className");
            System.out.println(className);
        }
    }

    配合使用樣例

    首先我們創(chuàng)建一個(gè)屬性配置文件,如下:

    className = User
    fieldName = name
    fieldValue = zhangsan

    樣例代碼如下:

    public class ReflectTest07 {
        public static void main(String[] args) throws Exception{
            //配合屬性文件使用
            ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
            Class c2 = Class.forName(bundle.getString("className"));
            //通過反射實(shí)例化User類
            Object obj = c2.newInstance();
            Field field1 = c2.getDeclaredField(bundle.getString("fieldName"));
            //打破封裝
            field1.setAccessible(true);
            field1.set(obj,bundle.getString("fieldValue"));
            System.out.println(field1.get(obj));
        }
    }

    通過反射機(jī)制獲取類中方法

    代碼如下:

    public class ReflectTest08 {
        public static void main(String[] args)throws Exception {
            Class c = Class.forName("java.lang.String");
            Method[] methods = c.getDeclaredMethods();
            StringBuffer s = new StringBuffer();
            for(Method m:methods){
                Class[] parameterTypes = m.getParameterTypes();
                s.append(Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName() + "(");
                for(Class cs:parameterTypes){
                    s.append(cs.getSimpleName() + " ");
                }
                s.append("){}\n");
            }
            System.out.println(s);
        }
    }

    編譯結(jié)果:

    Java反射機(jī)制怎么使用

    通過反射機(jī)制調(diào)用Java對(duì)象的方法

    使用反射機(jī)制調(diào)用一個(gè)對(duì)象的方法,步驟如下:

    • 獲取對(duì)應(yīng)類的Class對(duì)象。

    • 通過反射機(jī)制實(shí)例化出一個(gè)對(duì)象。

    • 通過方法 :public Method getDeclaredMethod(String name, Class... parameterTypes),獲取對(duì)應(yīng)的Method對(duì)象

    注意:getDeclaredMethod方法是在java.lang.Class下的方法,第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是可變長(zhǎng)參數(shù),是該方法的形式參數(shù)類型列表

    • 通過方法:public Object invoke(Object obj,Object... args),可以調(diào)用Method對(duì)象對(duì)應(yīng)的方法。

    注意:該方法是java.lang.reflect.Method下的方法,第一個(gè)參數(shù)是對(duì)象,第二個(gè)參數(shù)是方法的實(shí)際參數(shù)列表。

    往User類中添加方法,如下:

    public class User {
        //四個(gè)Field對(duì)象,分別采用四種不同的訪問權(quán)限修飾符
        public int no;
        private String name;
        protected  int age;
        boolean sex;
        public int doSome(int i){
            System.out.println("User對(duì)象中的doSome方法執(zhí)行!");
            return i;
        }
    }

    代碼如下:

    public class ReflectTest09 {
        public static void main(String[] args)throws Exception {
            Class c = Class.forName("User");
            Object obj = c.newInstance();
            Method method = c.getDeclaredMethod("doSome",int.class);
            System.out.println(method.invoke(obj,1));
        }
    }

    編譯結(jié)果如下:

    Java反射機(jī)制怎么使用

    通過反射機(jī)制獲取類中的構(gòu)造方法

    public class ReflectTest10 {
        public static void main(String[] args)throws Exception {
            Class c = Class.forName("java.lang.String");
            Constructor[] constructors = c.getDeclaredConstructors();
            StringBuffer s = new StringBuffer();
            for(Constructor co: constructors){
                s.append(Modifier.toString(co.getModifiers()) + " " +c.getSimpleName() + "(");
                Class[] parameterType = co.getParameterTypes();
                for(Class cs:parameterType){
                    s.append(cs.getSimpleName()+" ");
                }
                s.append("){}\n");
            }
            System.out.println(s);
        }
    }

    編譯結(jié)果如下:

    Java反射機(jī)制怎么使用

    通過反射機(jī)制創(chuàng)建對(duì)象(調(diào)用構(gòu)造方法)

    代碼如下:

    public class ReflectTest11 {
        public static void main(String[] args)throws Exception {
            Class c = Class.forName("User");
            //默認(rèn)調(diào)用無參數(shù)構(gòu)造方法
            Object obj1 = c.newInstance();
            //因?yàn)槊恳粋€(gè)構(gòu)造方法的方法名都一樣,所以getDeclaredConstructor方法的參數(shù)只有要調(diào)用的構(gòu)造方法的構(gòu)造參數(shù)類型列表
            Constructor constructor = c.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
            Object obj2 = constructor.newInstance(1111,"zhangsan",18,true);
            System.out.println(obj2);
        }
    }

    通過反射機(jī)制獲取一個(gè)類的父類和父接口

    代碼如下:

    public class ReflectTest12 {
        public static void main(String[] args)throws Exception {
            Class c = Class.forName("java.lang.String");
            //一個(gè)類最多只有一個(gè)父類
            Class superClass = c.getSuperclass();
            System.out.println(superClass.getName());
            //一個(gè)類可以實(shí)現(xiàn)多個(gè)接口
            Class[] superInterfaces = c.getInterfaces();
            for(Class i: superInterfaces){
                System.out.println(i.getName());
            }
        }
    }

    編譯結(jié)果如下:

    Java反射機(jī)制怎么使用

    以上就是“Java反射機(jī)制怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI