java反射筆記整理

                                     java反射筆記整理

一、反射基礎

1.Class對象的三種獲取方式

    @Test
    public void threeMethodForClassObj() throws ClassNotFoundException {
        //1.每個類都有一個隱藏的靜態變量class
        Class clazz1 = UserInfo.class;
        //2.使用最多的獲取class的方式,只要知道全類名就可以獲取到,會拋ClassNotFountException
        Class clazz2 = Class.forName("com.huangliwei.entity.UserInfo");
        //3.對象繼承至Object的方法
        UserInfo userInfo = new UserInfo();
        Class clazz3 = userInfo.getClass();
        log.debug("clazz1 [%s],clazz2[%s] 是否是同一個對象 %s", clazz1, clazz2, clazz1 == clazz2);
        log.debug("clazz1 [%s],clazz3[%s] 是否是同一個對象 %s", clazz1, clazz3, clazz1 == clazz3);
        //由此可見jvm中每個類只會有一個Class對象
    }

2.獲取父類class對象

    /**
     * 獲取父類class對象,由於單一繼承特性,所以只會獲取到一個class對象
     */
    @Test
    public void getSupperClass(){
        Class clazz = UserInfo.class;
        Class superclass = clazz.getSuperclass();
        log.debug("獲取父類class對象爲:%s",superclass.getName());
    }

3.獲取實現的接口class對象

    /**
     * 獲取類實現的所有接口<由於接口可以多實現,所以獲取的接口爲一個數組
     * 只能獲取到當前類實現的接口,不能獲取到父類實現的接口
     */
    @Test
    public void getInterfaces() {
        Class clazz = UserInfo.class;
        Class[] interfaces = clazz.getInterfaces();
        for (Class interfaceClass : interfaces) {
            log.debug("獲取實現的接口爲:%s", interfaceClass.getName());
        }
    }

二、反射常用對象

1.常用對象-Field

      a.獲取Field的兩種方式對比

 /**
     * 根據class對象獲取類的成員變量
     * @throws NoSuchFieldException
     */
    @Test
    public void getFields() throws NoSuchFieldException {
        Class<UserInfo> clazz = UserInfo.class;
        //獲取當前類的public修飾的所有成員變量,包括集成而來的
        Field[] fields1 = clazz.getFields();
        for (Field field : fields1) {
            log.debug("獲取public 變量:%s", field.getName());
        }
        //獲取當前類所有的變量,private、protected、public……以及從父類繼承過來的public類型的變量
        Field[] fields2 = clazz.getDeclaredFields();
        for (Field field : fields2) {
            log.debug("獲取當前類所有變量:%s", field.getName());
        }
        //還可以指定變量名獲取類的變量
        Field idField = clazz.getField("id");
        log.debug("指定名稱獲取public變量:%s", idField.getName());
        Field usernameField = clazz.getDeclaredField("username");
        log.debug("指定名稱獲取變量:%s", usernameField.getName());
    }

     b.遞歸獲取類的所有成員變量,包括父類所有成員變量

  @Test
    public void getAllFields() {
        Map<String, List<Field>> map = new HashMap<>();
        Class tempClass = UserInfo.class;
        while (tempClass != null) {
            //遞歸逐層獲取所有的類的私有變量
            String className = tempClass.getName();
            List<Field> fields = map.get(className);
            fields = fields == null ? new ArrayList<Field>() : fields;
            fields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            if (!map.containsKey(className)) {
                map.put(className, fields);
            }
            tempClass = tempClass.getSuperclass();
        }
        Set<String> classNames = map.keySet();
        for (String className : classNames) {
            List<Field> fields = map.get(className);
            for (Field field : fields) {
                log.debug("遞歸獲取所有類的成員變量%s.%s", className, field.getName());
            }
        }
    }

     c.獲取成員變量的修飾符

    /**
     * 變量的修飾符是通過int類型的數字表示的
     * 常見的數字與修飾符關係如下
     *  int publicCode = Modifier.PUBLIC;//1
        int privateCode = Modifier.PRIVATE;//2
        int protectedCode = Modifier.PROTECTED;//4
        int staticCode = Modifier.STATIC;//8
     */
    @Test
    public void getFieldModifiers(){

        Class clazz=UserInfo.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field :fields)
        {
            int modify = field.getModifiers();
            log.debug("獲取成員變量的修飾符field=%s---modifer=%s",field.getName(),modify);
        }

    }

     d.獲取成員變量的數據類型

    /**
     * 獲取變量的類型之後可以通過判斷變量類型給變量賦值
     */
    @Test
    public void getFieldType(){
        Class clazz=UserInfo.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field :fields)
        {
            Type type = field.getGenericType();
            //其實這樣獲取的就是這個類的class對象
            Class fieldClazz= (Class) type;
            log.debug("獲取成員變量的修飾符field=%s---type=%s",field.getName(),fieldClazz.getName());
        }
    }

2.常用對象-Method

 

3.常用對象-Constructor

三、反射基本應用

四、反射與泛型

五、反射與枚舉

六、總結

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章