国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java學習:用反射構造bean

2019-11-14 15:23:09
字體:
來源:轉載
供稿:網友

先貼一些反射的基本知識:
--------------------------------------------------------------------

一、什么是反射:
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。這一概念的提 出很快引發了計算機科學領域關于應用反射性的研究。它首先被程序語言的設計領域所采用,并在Lisp和面向對象方面取得了成績。其中 LEAD/LEAD++ 、OpenC++ 、MetaXa和Openjava等就是基于反射機制的語言。最近,反射機制也被應用到了視窗系統、操作系統和文件系統中。

反射本身并不 是一個新概念,盡管計算機科學賦予了反射概念新的含義。在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過采用某種機 制來實現對自己行為的描述(self-rePResentation)和監測(examination),并能根據自身行為的狀態和結果,調整或修改應用 所描述行為的狀態和相關的語義。

二、什么是Java中的類反射:
Reflection 是 Java 程序開發語言的特征之一,它允許運行中的 Java 程序對自身進行檢查,或者說“自審”,并能直接操作程序的內部屬性和方法。Java 的這一能力在實際應用中用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
Reflection 是 Java 被視為動態(或準動態)語言的關鍵,允許程序于執行期 Reflection APIs 取得任何已知名稱之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于執行期生成instances、變更 fields 內容或喚起 methods。

三、Java類反射中所必須的類:
Java的類反射所需要的類并不多,它們分別是:Field、Constructor、Method、Class、Object,下面我將對這些類做一個簡單的說明。
Field類:提供有關類或接口的屬性的信息,以及對它的動態訪問權限。反射的字段可能是一個類(靜態)屬性或實例屬性,簡單的理解可以把它看成一個封裝反射類的屬性的類。
Constructor類:提供關于類的單個構造方法的信息以及對它的訪問權限。這個類和Field類不同,Field類封裝了反射類的屬性,而Constructor類則封裝了反射類的構造方法。
Method類:提供關于類或接口上單獨某個方法的信息。所反映的方法可能是類方法或實例方法(包括抽象方法)。 這個類不難理解,它是用來封裝反射類方法的一個類。
Class類:類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬于被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
Object類:每個類都使用 Object 作為超類。所有對象(包括數組)都實現這個類的方法。

 

以上來自 http://www.survivalescaperooms.com/forlina/archive/2011/06/21/2085849.html

--------------------------------------------------------------------

反射的優勢在于它可以在程序運行期間動態地構造對象,比較常見的例子是json格式的字符串轉化成對象,可以找一些源碼參看。

最近寫了個方法,用反射的方式根據xml文件和配置文件構造所需的對象,分享在這里。

public static <T> T createObjectFromXMLAndProperty(Document document, Map<String, String> config, Class<T> clazz)

document:xml文件生成的Document對象,數據源

config:配置信息,標明構造的對象所需的數據在xml中的位置

clazz:目標對象

其中的config配置信息是要自己寫的,也有一定的寫法,例如:

a=xx

b=

c=/root/ele

d=/root/ele[@att]

e=/root/ele;/root/ele[@att]

f=/root/nodes/node[$]

g.aa=/root/nodes/node[$][@key]

g.bb=/root/nodes/node[$][@value]

"="左側是目標對象中的字段名,右側是數據/數據的xpath/多個數據

左側:a:目標對象中的a字段

     g.aa:目標對象中的g,中的aa字段

   同理,對于對象中不是基本類型的對象,用a.b.c....的形式構造

右側:具體的值

   空:默認值

   xpath:xpath指向的xml中的節點的value

   xpath[@att]:xpath指向的xml中的節點名為“att”的屬性

   xpath[$]:取出一系列數據,構造List(僅list可用)

   *;*;...:用";"分割的一系列數據構造目標字段(需要有相應的set方法)

以上的寫法可以互相搭配使用。

 

優點:以后遇到解析xml文件的情況時,只需要編寫一個配置文件即可,迭代速度快,之后若有改動也是改配置文件,代碼不用變動。

不足:只支持構造可以分解為基本類型和List的對象,還有一些類型待添加,如Map等等;

   當取數邏輯復雜時,無能為力,比如要取出比a節點的value大的所有節點,好好敲代碼吧——或者取出來再做處理。

 

代碼如下:

復制代碼
public class XMLAnalysisUtils {    private static final String REGEX_RULE = "http://[@(//w+)//]";    private static final Pattern pat = Pattern.compile(REGEX_RULE);    private static final Splitter splitter = Splitter.on(";");    private static Map<Type, AbstractStringConverter> typeMap = Maps.newHashMap();    /**     * 根據xml和properties構造對象,properties用于描述對象中的字段的值在xml中到位置     *     * @param document xml數據     * @param config   properties     * @param clazz    目標對象     * @return 對象實體     * @throws Exception     */    public static <T> T createObjectFromXMLAndProperty(Document document, Map<String, String> config, Class<T> clazz)            throws Exception {        initTypeMap();        return (T) createObjectFromXMLAndProperty(document, config, clazz, "");    }    private static void initTypeMap() {        typeMap.put(boolean.class, new BooleanConverter());        typeMap.put(int.class, new IntegerConverter());        typeMap.put(double.class, new DoubleConverter());        typeMap.put(Boolean.class, new BooleanConverter());        typeMap.put(Integer.class, new IntegerConverter());        typeMap.put(Double.class, new DoubleConverter());        typeMap.put(String.class, new StringConverter());    }    private static Object createObjectFromXMLAndProperty(Document document, Map<String, String> properties, Class clazz, String owner)            throws Exception {        Method[] methods = clazz.getDeclaredMethods();        Object object = clazz.newInstance();        for (Method method : methods) {            String methodName = method.getName();            Type[] type = method.getGenericParameterTypes();            if (!methodName.startsWith("set")) {                continue;            }            String parameter = owner + methodName.substring(3, 4).toLowerCase() + methodName.substring(4);            String xPath = properties.get(parameter);            if (xPath != null) {                if (xPath.isEmpty()) {                    if (type.length == 1 && String.class == type[0]) {                        method.invoke(object, "");                    }                    continue;                }                if (!isBaseType(type)) {                    if (type[0] instanceof ParameterizedType) {                        ParameterizedType pt = (ParameterizedType) type[0];                        Type tp = pt.getActualTypeArguments()[0];                        if (!isBaseType(tp)) {                            continue;                        }                        Object results = createList(document, properties, tp, parameter);                        method.invoke(object, results);                    }                    continue;                }                List<String> values = getValue(document, xPath);                if (isAllNull(values)) {                    continue;                }                List<Object> result = transType(values, type);                if (result == null) {                    continue;                }                method.invoke(object, result.toArray());                continue;            }            if (isBaseType(type)) {                if (type.length == 1 && String.class == type[0]) {                    method.invoke(object, "");                }                continue;            }            if (type[0] instanceof Class) {                Object res = createObjectFromXMLAndProperty(document, properties, (Class) type[0], parameter + ".");                method.invoke(object, res);                continue;            }            if (type[0] instanceof ParameterizedType) {                ParameterizedType pt = (ParameterizedType) type[0];                if (pt.getRawType().equals(List.class)) {                    Type tp = pt.getActualTypeArguments()[0];                    Object results = createListObjectFromXMLAndProperty(document, properties, (Class) tp, parameter + ".");                    method.invoke(object, results);                }            }        }        return object;    }    private static Object createListObjectFromXMLAndProperty(Document document, Map<String, String> properties, Class clazz,                                                             String owner) throws Exception {        Method[] methods = clazz.getDeclaredMethods();        List<Object> objects = Lists.newArrayList();        Integer row = 1;        boolean mark = true;        boolean isList = true;        while (mark & isList) {            mark = false;            isList = false;            Object object = clazz.newInstance();            for (Method method : methods) {                String methodName = method.getName();                Type[] type = method.getGenericParameterTypes();                if (!methodName.startsWith("set")) {                    continue;                }                String parameter = owner + methodName.substring(3, 4).toLowerCase() + methodName.substring(4);                String xPath = properties.get(parameter);                if (xPath != null) {                    if (xPath.isEmpty()) {                        if (type.length == 1 && String.class == type[0]) {                            method.invoke(object, "");                        }                        continue;                    }                    if (xPath.contains("$")) {                        isList = true;                    }                    if (!isBaseType(type)) {                        if (type[0] instanceof ParameterizedType) {                            ParameterizedType pt = (ParameterizedType) type[0];                            Type tp = pt.getActualTypeArguments()[0];                            if (!isBaseType(tp)) {                                continue;                            }                            Object results = createList(document, properties, tp, parameter);                            method.invoke(object, results);                        }                        continue;                    }                    List<String> values = getValue(document, xPath.replaceAll("http://$", row.toString()));                    if (isAllNull(values)) {                        continue;                    }                    List<Object> result = transType(values, type);                    if (result == null) {                        continue;                    }                    mark = mark || xPath.contains("$");//非固定值被invoke時判定為可繼續                    method.invoke(object, result.toArray());                    continue;                }                if (isBaseType(type)) {                    if (type.length == 1 && String.class == type[0]) {                        method.invoke(object, "");                    }                    continue;                }                if (type[0] instanceof Class) {                    logger.debug("type0:{}, method.name{}", type[0].toString(), method.getName());                    Object res = createObjectFromXMLAndProperty(document, properties, (Class) type[0], parameter + ".");                    method.invoke(object, res);                    continue;                }                if (type[0] instanceof ParameterizedType) {                    ParameterizedType pt = (ParameterizedType) type[0];                    if (pt.getRawType().equals(List.class)) {                        Type tp = pt.getActualTypeArguments()[0];                        Object results = createListObjectFromXMLAndProperty(document, properties, (Class) tp, parameter + ".");                        method.invoke(object, results);                    }                }            }            objects.add(object);            row++;        }        objects.remove(objects.size() - 1);        return objects;    }    private static Object createList(Document document, Map<String, String> properties, Type type, String parameter) {        List<Object> objects = Lists.newArrayList();        Integer row = 1;        boolean mark = true;        boolean isList = true;        while (mark & isList) {            mark = false;            String xPath = properties.get(parameter);            if (xPath == null) {                return null;            }            if (xPath.isEmpty()) {                return objects;            }            if (!xPath.contains("$")) {                isList = false;            }            xPath = xPath.replaceAll("http://$", row.toString());            List<String> values = getValue(document, xPath);            if (isAllNull(values)) {                continue;            }            List<Object> result = transType(values, type);            if (result == null) {                continue;            }            mark = true;            objects.add(result.get(0));            row++;        }        return objects;    }    private static List<Object> transType(List<String> values, Type... types) {        if (values.size() != types.length) {            return null;        }        List<Object> result = Lists.newArrayList();        int len = values.size();        for (int i = 0; i < len; i++) {            result.add(typeMap.get(types[i]).doForward(values.get(i)));        }        return result;    }    private static List<String> getValue(Document document, String xPath) {        List<String> paths = splitter.splitToList(xPath);        List<String> values = Lists.newArrayList();        for (String path : paths) {            if (!path.startsWith("/")) {                values.add(path);                continue;            }            Element element;            element = (Element) document.selectSingleNode(path);            if (element == null) {                values.add(null);                continue;            }            if (path.contains("@")) {                Matcher match = pat.matcher(path);                if (match.find()) {                    String attr = match.group(1);                    values.add(element.attributeValue(attr));                }                continue;            }            values.add(element.getStringValue());        }        return values;    }    private static boolean isBaseType(Type... types) {        return typeMap.keySet().containsAll(Lists.newArrayList(types));    }    private static boolean isAllNull(List<String> values) {        boolean result = true;        if (values == null) {            return true;        }        for (String value : values) {            result = result && value == null;        }        return result;    }}
復制代碼

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 马鞍山市| 江北区| 亚东县| 佛学| 罗山县| 兰西县| 新源县| 徐汇区| 若羌县| 梁平县| 民权县| 申扎县| 永定县| 浠水县| 汨罗市| 苏尼特右旗| 林州市| 泾川县| 资兴市| 喀喇| 醴陵市| 澜沧| 南乐县| 西充县| 时尚| 象山县| 达尔| 清水河县| 即墨市| 合山市| 安吉县| 河东区| 保定市| 旅游| 松潘县| 响水县| 德格县| 邻水| 汽车| 平遥县| 博兴县|