国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關(guān)于屬性描述符PropertyDescriptor

lewif / 3053人閱讀

摘要:一些使用方式其實在我上面寫一些構(gòu)造函數(shù)的時候,我想大家應該已經(jīng)感受到與反射相關(guān)了,起碼我感覺上是這樣的,所以我一開始想到這樣的案例形式,通過反射與這個屬性描述類去賦予我的類。

本文首發(fā)于本博客 貓叔的博客,轉(zhuǎn)載請申明出處
前言
感謝GY丶L粉絲的提問:屬性描述器PropertyDescriptor是干嘛用的?

本來我也沒有仔細了解過描述符這一塊的知識,不過粉絲問了,我就抽周末的時間看看,順便學習一下,粉絲問的剛好是PropertyDescriptor這個屬性描述符,我看了下源碼。

/**
 * A PropertyDescriptor describes one property that a Java Bean
 * exports via a pair of accessor methods.
 */
public class PropertyDescriptor extends FeatureDescriptor {
    //...
}

emmmm,假裝自己英語能厲害的說,屬性描述符描述了一個屬性,即Java Bean 通過一對訪問器方法來導出。(沒錯,他確實是存在于java.beans包下的)

通過類關(guān)系圖,可以知道,我們應該提前了解一下FeatureDescriptor才行了。很好,起碼目前還沒有設(shè)計抽象類或者接口。

FeatureDescriptor
/**
 * The FeatureDescriptor class is the common baseclass for PropertyDescriptor,
 * EventSetDescriptor, and MethodDescriptor, etc.
 * 

* It supports some common information that can be set and retrieved for * any of the introspection descriptors. *

* In addition it provides an extension mechanism so that arbitrary * attribute/value pairs can be associated with a design feature. */ public class FeatureDescriptor { //... }

okay,這是很合理的設(shè)計方式,F(xiàn)eatureDescriptor為類似PropertyDescriptor、EvebtSetDescriptor、MethodDescriptor的描述符提供了一些共用的常量信息。同時它也提供一個擴展功能,方便任意屬性或鍵值對可以于設(shè)計功能相關(guān)聯(lián)。

這里簡單的說下,在我大致看了一下源碼后(可能不夠詳細,最近有點忙,時間較趕),F(xiàn)eatureDescriptor主要是針對一下屬性的一些get/set,同時這些屬性都是基本通用于PropertyDescriptor、EvebtSetDescriptor、MethodDescriptor。

    private boolean expert; // 專有
    private boolean hidden; // 隱藏
    private boolean preferred; // 首選
    private String shortDescription; //簡單說明
    private String name; // 編程名稱
    private String displayName; //本地名稱
    private Hashtable table; // 屬性表

其實該類還有另外幾個方法,比如深奧的構(gòu)造函數(shù)等等,這里就不深入探討了。

PropertyDescriptor

那么我們大致知道了FeatureDescriptor,接下來就可以來深入了解看看這個屬性描述符PropertyDescriptor

說到屬性,大家一定會想到的就是get/set這個些基礎(chǔ)的東西,當我打開PropertyDescriptor源碼的時候,我也看到了一開始猜想的點。

    private final MethodRef readMethodRef = new MethodRef();
    private final MethodRef writeMethodRef = new MethodRef();
    private String writeMethodName;
    private String readMethodName;

這里的代碼是我從源碼中抽離的一部分,起碼我們這樣看可以大致理解,是分為寫和讀的步驟,那么就和我們初學java的get/set是一致的。

同時我還看到了,這個,及其注釋。

    // The base name of the method name which will be prefixed with the
    // read and write method. If name == "foo" then the baseName is "Foo"
    private String baseName;

這好像可以解釋,為什么我們的屬性在生成get/set的時候,第一個字母變成大寫?!注釋好像確實是這樣寫的。

由于可能需要一個Bean對象,所以我以前在案例中先創(chuàng)建了一個Cat類。

public class Cat {

    private String name;

    private String describe;

    private int age;

    private int weight;

    public String getName() {
        return name;
    }

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

    public String getDescribe() {
        return describe;
    }

    public void setDescribe(String describe) {
        this.describe = describe;
    }

    public int getAge() {
        return age;
    }

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

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}
構(gòu)造函數(shù)

起碼目前,我還不知道我應該怎么使用它,那么我們就一步一步來吧,我看到它有好幾個構(gòu)造函數(shù),這是一個有趣而且有難度的事情,我們先試著創(chuàng)建一個PropertyDescriptor吧。

第一種構(gòu)造函數(shù)

    /**
     * Constructs a PropertyDescriptor for a property that follows
     * the standard Java convention by having getFoo and setFoo
     * accessor methods.  Thus if the argument name is "fred", it will
     * assume that the writer method is "setFred" and the reader method
     * is "getFred" (or "isFred" for a boolean property).  Note that the
     * property name should start with a lower case character, which will
     * be capitalized in the method names.
     *
     * @param propertyName The programmatic name of the property.
     * @param beanClass The Class object for the target bean.  For
     *          example sun.beans.OurButton.class.
     * @exception IntrospectionException if an exception occurs during
     *              introspection.
     */
    public PropertyDescriptor(String propertyName, Class beanClass)
                throws IntrospectionException {
        this(propertyName, beanClass,
                Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName),
                Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName));
    }

這個好像是參數(shù)最少的,它只需要我們傳入一個屬性字符串,還有對應的類就好了,其實它也是調(diào)用了另一個構(gòu)造函數(shù),只是它會幫我們默認生成讀方法和寫方法。方法中的Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName)其實就是自己拼出一個默認的get/set方法,大家有興趣可以去看看源碼。

那么對應的實現(xiàn)內(nèi)容,我想大家應該都想到了。

    public static void main(String[] args) throws Exception {
        PropertyDescriptor CatPropertyOfName = new PropertyDescriptor("name", Cat.class);
        System.out.println(CatPropertyOfName.getPropertyType());
        System.out.println(CatPropertyOfName.getPropertyEditorClass());
        System.out.println(CatPropertyOfName.getReadMethod());
        System.out.println(CatPropertyOfName.getWriteMethod());
    }

第二種構(gòu)造函數(shù)

/**
     * This constructor takes the name of a simple property, and method
     * names for reading and writing the property.
     *
     * @param propertyName The programmatic name of the property.
     * @param beanClass The Class object for the target bean.  For
     *          example sun.beans.OurButton.class.
     * @param readMethodName The name of the method used for reading the property
     *           value.  May be null if the property is write-only.
     * @param writeMethodName The name of the method used for writing the property
     *           value.  May be null if the property is read-only.
     * @exception IntrospectionException if an exception occurs during
     *              introspection.
     */
    public PropertyDescriptor(String propertyName, Class beanClass,
                String readMethodName, String writeMethodName)
                throws IntrospectionException {
        if (beanClass == null) {
            throw new IntrospectionException("Target Bean class is null");
        }
        if (propertyName == null || propertyName.length() == 0) {
            throw new IntrospectionException("bad property name");
        }
        if ("".equals(readMethodName) || "".equals(writeMethodName)) {
            throw new IntrospectionException("read or write method name should not be the empty string");
        }
        setName(propertyName);
        setClass0(beanClass);

        this.readMethodName = readMethodName;
        if (readMethodName != null && getReadMethod() == null) {
            throw new IntrospectionException("Method not found: " + readMethodName);
        }
        this.writeMethodName = writeMethodName;
        if (writeMethodName != null && getWriteMethod() == null) {
            throw new IntrospectionException("Method not found: " + writeMethodName);
        }
        // If this class or one of its base classes allow PropertyChangeListener,
        // then we assume that any properties we discover are "bound".
        // See Introspector.getTargetPropertyInfo() method.
        Class[] args = { PropertyChangeListener.class };
        this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
    }

沒錯,這個構(gòu)造函數(shù)就是第一種構(gòu)造函數(shù)內(nèi)部二次調(diào)用的,所需要的參數(shù)很簡單,同時我也希望大家可以借鑒這個方法中的一些檢測方式。這次的實現(xiàn)方式也是同樣的形式。

    public static void main(String[] args) throws Exception {
        PropertyDescriptor CatPropertyOfName = new PropertyDescriptor("name", Cat.class,"getName","setName");
        System.out.println(CatPropertyOfName.getPropertyType());
        System.out.println(CatPropertyOfName.getPropertyEditorClass());
        System.out.println(CatPropertyOfName.getReadMethod());
        System.out.println(CatPropertyOfName.getWriteMethod());
    }

第三種構(gòu)造函數(shù)

    /**
     * This constructor takes the name of a simple property, and Method
     * objects for reading and writing the property.
     *
     * @param propertyName The programmatic name of the property.
     * @param readMethod The method used for reading the property value.
     *          May be null if the property is write-only.
     * @param writeMethod The method used for writing the property value.
     *          May be null if the property is read-only.
     * @exception IntrospectionException if an exception occurs during
     *              introspection.
     */
    public PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
                throws IntrospectionException {
        if (propertyName == null || propertyName.length() == 0) {
            throw new IntrospectionException("bad property name");
        }
        setName(propertyName);
        setReadMethod(readMethod);
        setWriteMethod(writeMethod);
    }

這個不用傳類,因為你需要傳遞兩個實際的方法進來,所以主要三個對應屬性的參數(shù)既可。看看大致的實現(xiàn)內(nèi)容

    public static void main(String[] args) throws Exception {
        Class classType = Cat.class;
        Method CatNameOfRead = classType.getMethod("getName");
        Method CatNameOfWrite = classType.getMethod("setName", String.class);
        PropertyDescriptor CatPropertyOfName = new PropertyDescriptor("name", CatNameOfRead,CatNameOfWrite);
        System.out.println(CatPropertyOfName.getPropertyType());
        System.out.println(CatPropertyOfName.getPropertyEditorClass());
        System.out.println(CatPropertyOfName.getReadMethod());
        System.out.println(CatPropertyOfName.getWriteMethod());
    }

好了,大致介紹了幾種構(gòu)造函數(shù)與實現(xiàn)方式,起碼我們現(xiàn)在知道它需要什么。

一些使用方式

其實在我上面寫一些構(gòu)造函數(shù)的時候,我想大家應該已經(jīng)感受到與反射相關(guān)了,起碼我感覺上是這樣的,所以我一開始想到這樣的案例形式,通過反射與這個屬性描述類去賦予我的類。

    public static void main(String[] args) throws Exception {
        //獲取類
        Class classType = Class.forName("com.example.demo.beans.Cat");
        Object catObj = classType.newInstance();
        //獲取Name屬性
        PropertyDescriptor catPropertyOfName = new PropertyDescriptor("name",classType);
        //得到對應的寫方法
        Method writeOfName = catPropertyOfName.getWriteMethod();
        //將值賦進這個類中
        writeOfName.invoke(catObj,"river");
        Cat cat = (Cat)catObj;
        System.out.println(cat.toString());
    }

運行結(jié)果還是順利的。

Cat{name="river", describe="null", age=0, weight=0}

可以看到,我們確實得到了一個理想中的對象。

那么我是不是可以改變一個已經(jīng)創(chuàng)建的對象呢?

    public static void main(String[] args) throws Exception {
        //一開始的默認對象
        Cat cat = new Cat("river","黑貓",2,4);
        //獲取name屬性
        PropertyDescriptor catPropertyOfName = new PropertyDescriptor("name",Cat.class);
        //得到讀方法
        Method readMethod = catPropertyOfName.getReadMethod();
        //獲取屬性值
        String name = (String) readMethod.invoke(cat);
        System.out.println("默認:" + name);
        //得到寫方法
        Method writeMethod = catPropertyOfName.getWriteMethod();
        //修改值
        writeMethod.invoke(cat,"copy");
        System.out.println("修改后:" + cat);
    }

上面的demo是,我先創(chuàng)建了一個對象,然后通過屬性描述符讀取name值,再進行修改值,最后輸出的對象的值也確實改變了。

默認:river
修改后:Cat{name="copy", describe="黑貓", age=2, weight=4}
收尾

這是一個有趣的API,我想另外兩個(EvebtSetDescriptor、MethodDescriptor)應該也差不多,大家可以再通過此方法去探究,只有自己嘗試一次才能學到這里面的一些東西,還有一些項目場景的使用方式,不過一般的業(yè)務場景應該很少使用到這個API。那么這個東西究竟可以干什么呢?我想你試著敲一次也許有一些答案了。

公眾號:Java貓說
現(xiàn)架構(gòu)設(shè)計(碼農(nóng))兼創(chuàng)業(yè)技術(shù)顧問,不羈平庸,熱愛開源,雜談程序人生與不定期干貨。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/73099.html

相關(guān)文章

  • 詳敘BeanWrapper和PropertyDescriptor

    摘要:關(guān)于它的數(shù)據(jù)轉(zhuǎn)換使用了如下兩種機制隸屬于規(guī)范。這種類中的方法主要用于訪問私有的字段,且方法名符合某種命名規(guī)則。如果在兩個模塊之間傳遞信息,可以將信息封裝進中,這種對象稱為值對象,或。 每篇一句 千古以來要飯的沒有要早飯的,知道為什么嗎? 相關(guān)閱讀 【小家Spring】聊聊Spring中的數(shù)據(jù)轉(zhuǎn)換:Converter、ConversionService、TypeConverter、Pro...

    APICloud 評論0 收藏0
  • Spring IOC 容器源碼分析 - 填充屬性到 bean 原始對象

    摘要:源碼分析源碼一覽本節(jié),我們先來看一下填充屬性的方法,即。所有的屬性值是在方法中統(tǒng)一被注入到對象中的。檢測是否存在與相關(guān)的或。這樣可以在很大程度上降低源碼分析的難度。若候選項是非類型,則表明已經(jīng)完成了實例化,此時直接返回即可。 1. 簡介 本篇文章,我們來一起了解一下 Spring 是如何將配置文件中的屬性值填充到 bean 對象中的。我在前面幾篇文章中介紹過 Spring 創(chuàng)建 bea...

    SKYZACK 評論0 收藏0
  • 利用反射和注解,拷貝類型相同,屬性名不同的對象

    摘要:前言最近開發(fā)遇到一個問題,兩個對象進行屬性值拷貝。理論上來說可以直接借助來進行拷貝,奈何兩個對象屬性名不同,懵逼臉。 1、前言 最近開發(fā)遇到一個問題,兩個對象進行屬性值拷貝。理論上來說可以直接借助org.springframework.beans.BeanUtils.copyProperties(Object source, Object target)來進行拷貝,奈何兩個對象屬性名不...

    forrest23 評論0 收藏0
  • Spring詳解4.容器內(nèi)幕

    摘要:在這一步里,將配置文件的信息裝入到容器的定義注冊表中,但此時還未初始化。注冊后處理器根據(jù)反射機制從中找出所有類型的,并將它們注冊到容器后處理器的注冊表中。是屬性編輯器的注冊表,主要作用就是注冊和保存屬性編輯器。 點擊進入我的博客 1 Spring容器整體流程 1.1 ApplicationContext內(nèi)部原理 AbstractApplicationContext是Applicati...

    dantezhao 評論0 收藏0
  • Spring BeanUtils源碼分析

    摘要:前置知識在分析源碼前,我們先溫習一下以下的知識點。類在中萬物皆對象,而且我們在代碼中寫的每一個類也都是對象,是類的對象。總結(jié)一個看似簡單的工具類,其實里面包含的基礎(chǔ)的知識點非常多,包括類型信息反射線程安全引用類型類加載器等。 背景 在我們著手一個Java Web項目的時候,經(jīng)常會遇到DO、VO、DTO對象之間的屬性拷貝,若采用get、set的方法來進行賦值的話,代碼會相當冗長丑陋,一般...

    darkbug 評論0 收藏0

發(fā)表評論

0條評論

lewif

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<