1. 程式人生 > >java反射和註解

java反射和註解

ReflectionAndAnnotation

本文講解java的 Reflect、Annotation 反射 和 註解的使用
文中的測試程式碼請前往 ReflectAndAnnotation

反射

本文主要從應用的角度講解反射。

先寫一個Bean類,定義int型的age, String name, List beans。

package com.example.dj.reflectandannotation;

import java.util.List;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
public class Bean {
    private int age;

    public String name;

    List<Bean> beans;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Bean> getBeans() {
        return beans;
    }

    public void setBeans(List<Bean> beans) {
        this.beans = beans;
    }

    @Override
    public String toString() {
        return "name = " + name + ", age = " + age;
    }
}

然後在BeanTest類進行測試:

package com.example.dj.reflectandannotation;

import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
public class BeanTest {

    private static final String TAG = "BeanTest";

    public static void testBean(){
        //定義一個bean的實體,然後初始化
        Bean bean = new Bean();
        List<Bean> beans = new ArrayList<>();
        beans.add(bean);
        bean.setAge(12);
        bean.setName("dragon");
        bean.setBeans(beans);

        Class clazz = bean.getClass();//取得類的物件

        Field[]  fields = clazz.getDeclaredFields();//取得類中所有屬性的集合

        try {
            for (Field field : fields) {
                if (!field.isAccessible()) {//如果這些屬性是不可訪問的,設為可訪問
                    field.setAccessible(true);
                }

                Class fieldType = field.getType();//取得該屬性的型別
                String strType = fieldType.toString();

                if(int.class.isAssignableFrom(fieldType)){//判斷該屬性是否int型別,取得屬性值
                    int i = (int) field.get(bean);
                    Log.d(TAG, strType + ", " + field.getName() + " = "+ i);

                } else if(String.class.isAssignableFrom(fieldType)){//判斷該屬性是否String型別,取得屬性值
                    String s = (String) field.get(bean);
                    Log.d(TAG, strType + ", " + field.getName() + " = "+ s);

                } else if(List.class.isAssignableFrom(fieldType)){//判斷該屬性是否List型別,如果是,取得List的引數型別
                    Type type = field.getGenericType();//取得該屬性的引數型別

                    if(type instanceof ParameterizedType){
                        Class itemClazz = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];//取得list的實際引數型別

                        if(Bean.class.isAssignableFrom(itemClazz)){//判斷型別是否Bean型別
                            List list = (List) field.get(bean);//取得List
                            Iterator it = list.iterator();
                            while (it.hasNext()){
                                Bean b = (Bean) it.next();//取得Bean
                                Log.d(TAG, strType + ", " + field.getName() + "; itemType = "
                                        + itemClazz.getSimpleName() + ", value : " + b.toString());
                            }
                        }
                    }

                }
            }

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

執行BeanTest.testBean();
打印出來的log如下:

11-20 11:23:34.750 7652-7652/? D/BeanTest: class java.lang.String, name = dragon
11-20 11:23:34.750 7652-7652/? D/BeanTest: interface java.util.List, beans; itemType = Bean, value : name = dragon, age = 12
11-20 11:23:34.750 7652-7652/? D/BeanTest: int, age = 12

通過反射分別取到了Bean定義的三個屬性值。舉一反三可以同樣的用反射呼叫類內部的方法。

註解

註解在安卓的開發中可以提供很大的便利。

定義三個註解類,分別是類註解、方法註解、屬性註解

類註解:

package com.example.dj.reflectandannotation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAnnotation {
}

方法註解:

package com.example.dj.reflectandannotation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation {
}

屬性註解:(註解可以帶有引數,相比前兩個註解,屬性註解增加了一個引數,用於測試帶引數的註解)

package com.example.dj.reflectandannotation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {
    /**
     * 註解的引數privacyType的值。
     */
    int PRIVACY = 0;      //隱私的屬性
    int PUBLIC = 1;       //公開的屬性

    int privacyType() default PRIVACY;
}

然後對Bean類進行修改,增加註解:

package com.example.dj.reflectandannotation;

import com.example.dj.reflectandannotation.annotation.ClassAnnotation;
import com.example.dj.reflectandannotation.annotation.FieldAnnotation;
import com.example.dj.reflectandannotation.annotation.MethodAnnotation;

import java.util.List;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
@ClassAnnotation
public class Bean {
    @FieldAnnotation(privacyType = FieldAnnotation.PRIVACY)
    private int age;

    @FieldAnnotation(privacyType = FieldAnnotation.PUBLIC)
    public String name;

    @FieldAnnotation(privacyType = FieldAnnotation.PRIVACY)
    List<Bean> beans;

    public int getAge() {
        return age;
    }

    @MethodAnnotation
    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Bean> getBeans() {
        return beans;
    }

    public void setBeans(List<Bean> beans) {
        this.beans = beans;
    }

    @Override
    public String toString() {
        return "name = " + name + ", age = " + age;
    }
}

在AnnotationTest類解析註解:

package com.example.dj.reflectandannotation;

import android.util.Log;

import com.example.dj.reflectandannotation.annotation.ClassAnnotation;
import com.example.dj.reflectandannotation.annotation.FieldAnnotation;
import com.example.dj.reflectandannotation.annotation.MethodAnnotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author DragonJiang
 * @date 2015/11/16
 * @Description:
 */
public class AnnotationTest {
    private static final String TAG = "AnnotationTest";

    public static void testAnnotation(){
        Bean bean = new Bean();
        List<Bean> beans = new ArrayList<>();
        beans.add(bean);
        bean.setAge(12);
        bean.setName("dragon");
        bean.setBeans(beans);

        //類註解
        Class clazz = bean.getClass();//取得類的物件
        ClassAnnotation ca = (ClassAnnotation) clazz.getAnnotation(ClassAnnotation.class);//取類的註解
        if(ca != null) {
            Log.d(TAG, "the class "+ clazz.getSimpleName() + " has ClassAnnotation : " + ca.toString());//列印註解
        }

        //方法註解
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods){
            MethodAnnotation ma = method.getAnnotation(MethodAnnotation.class);
            if(ma != null){
                Log.d(TAG, "the method " + method.getName() + " has MethodAnnotation : " + ma.toString());//列印註解
            }
        }

        //屬性註解
        Field[]  fields = clazz.getDeclaredFields();//取得類中所有屬性的集合
        for (Field field : fields) {
            FieldAnnotation fa = field.getAnnotation(FieldAnnotation.class);
            if(fa == null){
                continue;
            }

            int privacyType = fa.privacyType();
            if(privacyType == FieldAnnotation.PRIVACY){
                Log.d(TAG, field.getName() + " has FieldAnnotation : " + "privacyType == FieldAnnotation.PRIVACY");
            } else {
                Log.d(TAG, field.getName() + " has FieldAnnotation : " + "privacyType == FieldAnnotation.PUBLIC");
            }
        }
    }
}

執行AnnotationTest.testAnnotation();列印log:

11-20 11:23:34.750 7652-7652/? D/AnnotationTest: the class Bean has ClassAnnotation : @com.example.dj.reflectandannotation.annotation.ClassAnnotation()
11-20 11:23:34.750 7652-7652/? D/AnnotationTest: the method setAge has MethodAnnotation : @com.example.dj.reflectandannotation.annotation.MethodAnnotation()
11-20 11:23:34.754 7652-7652/? D/AnnotationTest: name has FieldAnnotation : privacyType == FieldAnnotation.PUBLIC
11-20 11:23:34.754 7652-7652/? D/AnnotationTest: beans has FieldAnnotation : privacyType == FieldAnnotation.PRIVACY
11-20 11:23:34.754 7652-7652/? D/AnnotationTest: age has FieldAnnotation : privacyType == FieldAnnotation.PRIVACY

相關推薦

Spring實戰-第一次內作業-Java反射註解

第一次內作業 詳細理解Java反射機制 反射是什麼 反射的作用用一句簡單的話來講就是可以對程式碼進行操作的程式碼,這個特性經常在被用於建立JavaBean中,通常造輪子的人會用到這個特性,而應用程式設計師用到這個特性的場景則較少。 能夠分析類能力的程式就

Java反射註解一些總結

Java 反射和註解的一些總結 反射 // There are five kinds of classes (or interfaces): // a) Top level classes // b) Nested classes (static m

java反射註解

ReflectionAndAnnotation 本文講解java的 Reflect、Annotation 反射 和 註解的使用 文中的測試程式碼請前往 ReflectAndAnnotation 反射 本文主要從應用的角度講解反射。 先寫一個Be

JAVA反射_註解

概念及作用 Java註解,從名字上看是註釋,解釋。但功能卻不僅僅是註釋那麼簡單。註解(Annotation)即元資料,就是原始碼的元資料註解(Annotation)為我們在程式碼中新增資訊提供了一種形式化的方法,使我們可以在稍後某個時刻方便地使用這些資料(通過解析註解來使用這些資料).

Java反射動態代理

反射和動態代理放有一定的相關性,但單純的說動態代理是由反射機制實現的,其實是不夠全面不準確的,動態代理是一種功能行為,而它的實現方法有很多。要怎麼理解以上這句話,請看下文。 一、反射 反射機制是 Java 語言提供的一種基礎功能,賦予程式在執行時自省(introspect,官方用語)的能力。

Spring 依賴注入實現原理--java反射ASM框架

依賴注入是spring的一個特性,從配置層面解決了程式耦合、依賴問題,spring提供了建構函式依賴注入、Setter方法依賴注入、自動裝配依賴注入和@autowired註解依賴注入等多種實現方式。 那麼依賴注入是如何實現的?第一反應就是java反射唄,比如建構

【知了堂學習筆記】JAVA反射註解--輕鬆學會註解

Java註解在程式開發中廣泛被使用,註解的使用更加的規範了程式,一般註解有兩個用法: 1.對程式本身做解釋 2.被其他程式讀取 註解比較常見的有如下幾種: 內建註解: @Override–>表示方法重寫。 如圖該方法父類沒有,不是重寫,所以程式碼會報錯!

spring 配置的三種方式:XML配置,JAVA配置註解配置

是否有了這些 IOC 註釋,我們就可以完全摒除原來 XML 配置的方式呢?答案是否定的。有以下幾點原因:註釋配置不一定在先天上優於 XML 配置。如果 Bean 的依賴關係是固定的,(如 Service 使用了哪幾個 DAO 類),這種配置資訊不會在部署時發生調整,那麼註釋配

Java反射註解

JAVA反射 主要是指程式可以訪問,檢測和修改它本身狀態或行為的一種能力,並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。 反射機制是什麼 面試有可能會問到,這句話不管你能不能理解,但是你只要記住就可以了 反射機制就是在執行狀態中,

spring 配置的兩種方式:JAVA配置註解配置

眾所周知,spring自從3.0開始以後,就全面推薦使用配置的方式進行程式碼編寫了,這種方式確實可以避免了之前一個專案裡面一大堆XML的情況,畢竟XML的可讀性實在不怎麼樣,而且一會寫JAVA,一會寫XML,確實還是蠻麻煩的 就目前來說spring的配置方式一

如何使用反射註解實現簡單的依賴注入

Spring Bean 應該是Spring被使用最多的功能 ,通過註解/xml配置 ,可以簡化大量的依賴程式碼 ,同時也提高了效率 .在試用了Guice和閱讀了部分Spring BeanFactory的原始碼後 ,也瞭解了一部分依賴注入的原理 ,自己寫了一個

android的反射註解

反射的文章http://www.cnblogs.com/lzq198754/p/5780331.html 反射是java中一種強大的工具,能夠使我們很方便的建立靈活的程式碼,這些程式碼可以再執行時裝配 1反射機制是什麼 反射機制是在執行狀態中,對於任意一個類,都

Java 反射對映(主要描述下反射)

什麼是反射?等同於對映嗎?     完全不相關的。反射是一個機機制,對映是一種關係。        反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼

java反射動態代理實現介面記錄

專案需求:app含有廣告sdk,在上架個別應用市場時會被拒,產品希望在打包時一些渠道包把廣告sdk剝離出來(內心是哭泣的)。方法一:每次打包刪除jar包,刪除與該jar包相關的程式碼類、介面等等~記錄完成,謝謝大家哈哈 開個玩笑,言歸正傳,以上是我一開始的想法,最笨最笨的方法

java反射代理機制

反射和代理機制是JDK5.0提供的java新特性,反射的出現打破了java一些常規的規則,如,私有變數不可訪問。但反射和代理在學習過程中也是一個比較難理解的知識點。本人曾經學過一段時間的反射和代理,但好長時間不用好像有點生疏了,當時學的時候就理解的不是很透徹,這次總結算是重

Class物件 java反射 AccessibleObject 類 註解

java 反射機制:在程式中獲取已載入到jvm中的java物件的資訊,並檢測或修改 獲取構造器 獲取成員變數 獲取方法 明顯 Accessible並不是標識方法能否訪問的. public的方法 Accessible仍為false  使用了method.setAccess

Java自定義註解執行時靠反射獲取註解

<span style="font-family:SimHei;font-size:18px;color:#663300;"><strong><span class="bh_code_a_Java_keywords">public</span> <span

Java反射、泛型註解實戰之Spring核心注入IOC的實現

一.前言 通過前兩篇文章的學習,我們已經對Java中這三個模組的知識有了初步的瞭解。為了將鞏固之前的知識,今天我們將綜合運用這三個模組的知識,來實現一個類似Spring中注入的案例。 二.專案結構 簡單的描繪了一下專案流程圖,

通過自定義註解java反射實現Spring-DI依賴注入

依賴注入的原理就是簡單說就是從頭往下遞迴生成依賴物件的,然後對引用欄位賦值最後返回。 這裡實現通過變數型別來生成相應的物件。 模擬一個使用者的註冊業務,首先是controller層呼叫service層,然後呼叫dao層程式碼實現儲存使用者。 檔案結構: UserC