java的内省和反射

         一次课堂中,听到有Spring的内省,之前都没有听到这个词,那么究竟什么Spring的内省,从前我只认为我懂了反射,自己快工作三年了,还是在工作中没有怎么运用,觉得工作就是写一些业务代码,没有用到什么高深的技术,很向往那种技术大牛,为什么他们能短暂的时间能掌握到一个技术这么深,而自己只有这么浅,这样一想,很快感到深深的自卑。但是

也激发自己求知欲。好了,废话不多说.

        反射是在程序运行过程中,可以动态的获取所有的属性、方法、构造器以及动态操作任意方法、狗仔器和修改属性值等。 而内省机制是通过BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性。

         首先新建一个实体bean  User:

public class User {

    private long id;

    private String name;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

     内省机制的实现,通过introspector获取一个的类的BeanInfo,第二个参数是到哪个类停止,获取到的Beandescriptor是这个bean的所有描述。里面包含

MethodDescriptor和 PropertyDescrptor分别描述的Bean的所有方法的描述和所有属性的描述。

User user = new User();

BeanInfo descriptor = Introspector.getBeanInfo(user.getClass(), Object.class);

BeanDescriptor beanDescriptor = descriptor.getBeanDescriptor();

System.out.println(beanDescriptor);

MethodDescriptor[] descriptor1 = descriptor.getMethodDescriptors();

for (MethodDescriptor methodDescriptor : descriptor1) {
System.out.println(methodDescriptor.toString());
}

PropertyDescriptor[] descriptor2 = descriptor.getPropertyDescriptors();

Stream.of(descriptor2).forEach(k -> {
String name = k.getName();
System.out.println("name:"+name);

try {
if("id".equals(k.getName())) {
k.getWriteMethod().invoke(user, new Object[]{10});
}
}catch (Exception e){
e.printStackTrace();
}
});

           而反射是程序运行时,获取类的属性和方法和构造器,,  并获取对应的方法,执行的对应的方法的。

        Field[] fields =  User.class.getDeclaredFields();

        for(Field field : fields){
            System.out.println(field.getName());
        }

        Method[] methods = User.class.getMethods();

        for(Method field : methods){
            System.out.println(field.getName());
        }

   反射遍历属性的时候是没有方法拿到他get set方法的,但是可以手动实现。如下代码

  Class userClz =  Class.forName(User.class.getName());

        Field[] fields = userClz.getDeclaredFields();

        for(Field field : fields){
            System.out.println(field.getName());

            if("id".equals(field.getName())) {
                Method getMethod = userClz.getDeclaredMethod("get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1));
                System.out.println("geteMethod:" + getMethod.getName());

                try {
                    Method wrtieMethod = userClz.getDeclaredMethod("set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), new Class[]{Long.class});
                    System.out.println("geteMethod" + wrtieMethod.getName());
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

        Method[] methods = User.class.getMethods();

        for(Method method : methods){
            System.out.println(method.getName());
        }
    }

       总的来时, java的内省是通过反射实现的,内省的使用场景是对于属性的操作更加便利,而反射则更使用调用除了get, set方法外的其他方法,就像springMVC中,

HandlerMapping, 是一个url对应一个Method, 当匹配到url的时候,会动态调用对应Controller里的方法。

      

 

posted on 2017-12-06 09:12  xjz1842  阅读(311)  评论(0)    收藏  举报

导航