PropertyDescriptor 详解

本文提供了一个实用的工具类PropertyUtil,该类通过反射机制实现了获取对象属性的PropertyDescriptor,并提供了设置和获取属性值的方法。适用于Java Bean操作场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PropertyDescriptor 详解](http://blog.youkuaiyun.com/z69183787/article/details/8443777)


转自 http://blog.youkuaiyun.com/z69183787/article/details/8443777
package com.zhoushun;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.beans.PropertyDescriptor;

public class PropertyUtil {
    @SuppressWarnings("unchecked")
    public static PropertyDescriptor getPropertyDescriptor(Class clazz, String propertyName) {
        StringBuffer sb = new StringBuffer();//构建一个可变字符串用来构建方法名称
        Method setMethod = null;
        Method getMethod = null;
        PropertyDescriptor pd = null;
        try {
            Field f = clazz.getDeclaredField(propertyName);//根据字段名来获取字段
            if (f!= null) {
                //构建方法的后缀
               String methodEnd = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
               sb.append("set" + methodEnd);//构建set方法
               setMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{ f.getType() });
               sb.delete(0, sb.length());//清空整个可变字符串
               sb.append("get" + methodEnd);//构建get方法
               //构建get 方法
               getMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{ });
               //构建一个属性描述器 把对应属性 propertyName 的 get 和 set 方法保存到属性描述器中
               pd = new PropertyDescriptor(propertyName, getMethod, setMethod);
            }
        } catch (Exception ex) {
                ex.printStackTrace();
        }

        return pd;
    }

    @SuppressWarnings("unchecked")
    public static void setProperty(Object obj,String propertyName,Object value){
        Class clazz = obj.getClass();//获取对象的类型
        PropertyDescriptor pd = getPropertyDescriptor(clazz,propertyName);//获取 clazz 类型中的 propertyName 的属性描述器
        Method setMethod = pd.getWriteMethod();//从属性描述器中获取 set 方法
        try {
            setMethod.invoke(obj, new Object[]{value});//调用 set 方法将传入的value值保存属性中去
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    public static Object getProperty(Object obj, String propertyName){
       Class clazz = obj.getClass();//获取对象的类型
       PropertyDescriptor pd = getPropertyDescriptor(clazz,propertyName);//获取 clazz 类型中的 propertyName 的属性描述器
       Method getMethod = pd.getReadMethod();//从属性描述器中获取 get 方法
       Object value =null ;
       try {
           value = getMethod.invoke(clazz, new Object[]{});//调用方法获取方法的返回值
       } catch (Exception e) {
           e.printStackTrace();
       }
       return value;//返回值
    }
}
TypeScript 装饰器是一种特殊类型的声明,它可以附加到类、方法、访问器、属性或参数上。它们允许我们在运行时修改类的行为或结构。 ### 类装饰器 ```typescript function logClass(target: Function) { console.log(target); } @logClass class MyClass {} ``` 在这个例子中,`logClass` 就是一个简单的类装饰器,它接收目标类作为其唯一参数,并打印出来。 ### 属性装饰器 属性装饰器可以用于观察、修改甚至替换类成员的定义。 ```typescript function configurable(value: boolean) { return function (target: any, propertyKey: string): void { let descriptor = Object.getOwnPropertyDescriptor(target, propertyKey) || { }; descriptor.configurable = value; Object.defineProperty(target, propertyKey, descriptor); } } class Person { @configurable(false) name!: string; constructor(name:string){ this.name = name; } } ``` 这里我们设置了一个不可配置的 `name` 属性。 ### 方法装饰器 ```typescript function enumerable(isEnumerable:boolean) { return function(target:Object, methodName:String, descriptor:PropertyDescriptor):void{ descriptor.enumerable = isEnumerable; } } class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @enumerable(false) greet() { return "Hello, " + this.greeting; } } ``` 在这里我们将greet方法设为了非枚举状态。 ### 参数装饰器 参数装饰器应用于类构造函数或方法的参数上。 ```typescript function required(target: Object, propertyName: string | symbol, index:number) { const metadataKey = `required_${propertyName.toString()}`; if(Array.isArray(target[metadataKey])){ target[metadataKey].push(index); }else{ target[metadataKey] = [index]; } } class Course { title!:string; constructor(title:string){ this.title = title; } enroll(@required studentName:string){ } } ``` 此示例展示了如何标记需要验证的参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值