Java内省

Posted 南阳客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java内省相关的知识,希望对你有一定的参考价值。

    大家都知道,Java给我提供了反射机制,使我们可以获取到每一个类的每一个属性和方法,并对此进行操作。但是利用反射来操作对象时过于麻烦,所以sun公司就基于反射机制给大家提供了一个更加简单实用的api,那就是内省(Introspector),而内省这套api将会使我们操作JavaBean的属性更加方便。

1.什么是Javabean?

①类必须是公共的

②类必须具备无参构造器

2.什么是Javabean的属性?

要理解内省的概念,我们先来理解一下什么叫Javabean的属性,下面我们猜下该Javabean有几个属性,并且该属性是哪几个?

public class Person{
    private String name;
    private String passwords;
    private int age;

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return passwords;
    }

    public void setPassword(String password) {
        this.passwords= password;
    }

}

正确答案是三个,属性分别为name、password、class属性。

我们再猜下下面的这个bean有几个属性?

public class Student {

    public String getName() {
        return "";
    }

    public void setName(String name) {
    }

    public String getPassword() {
        return "";
    }

    public void setPasswords(String password) {
    }

    public int getAge() {
        return 0;
    }

    public void setAge(int age) {
    }
}

正确答案是五个,属性分别为name、age、password、passwords,class

我们再看下面这个Javabean有几个属性

public class Teacher{
  
    public String getName() {
        return "";
    }

    public void setPassword(String password) {
    }
   protected void setAge(int age) {
    }
   private void setAge1(int age) {
    }
   void setAge2(int age) {
    }
}

正确答案是三个,分别为name、password、class。

到这里,可能小伙伴们可能有点晕。在我们分析之前,需要大家记住这么一个概念。一个Javabean有多少个属性,取决于它又有几个不同的且访问权限为public的setter方法或者几个不同getter方法。让我们来分析一波,就清楚了。第一个JavaBean Person,它的setName()和getName()这样我们就找到了它的第一个bean的属性,它的setAge()和getAge()我们就又找到了它的第二个属性,再加上Object的class属性,总共三个。

第二个JavaBean Student,它的setName()和getName()这样我们就找到了它的第一个bean的属性,它的getPassword()我们就找到了第二个属性,它的setPasswords()我们就找到了第三个属性,它的getAge()和setAge()这样我们就找到了它的第四个属性,再加上Object的class属性,总共五个。

第三个JavaBean Teacher,它的setName()这样我们就找到了它的第一个bean的属性它的setPassword()我们就找到了第二个属性,再加上Object的class属性,总共三个,虽然还有setAge()、setAge1()、setAge2()等setter方法,但是他们的访问权限都不是public,所以不是Javabean的属性。

理解了JavaBean的概念和Javabean的属性之后,我们通过两个测试方法来进行我们的demo的演示

1.创建一个简单的JavaBean Student

package com.day09;

public class Student {
    private String name;
    private String password;
    private int age;

    protected String getNames() {
        return name;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

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

2.利用Junit来演示进行演示测试

package com.day09;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class IntrospectorDemo {
    /**
     * 得到bean的所有属性
     * 
     * @throws IntrospectionException
     */
    @Test
    public void introspectorStudent() throws IntrospectionException {
        // 通过Introspector来获取Bean的信息,如果加上Object就代表不使用从Object中继承过来的属性,默认是全部
        BeanInfo beanInfo = Introspector.getBeanInfo(Student.class, Object.class);
        // 通过BeanInfo对象来获取属性的描述器数组
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            // 获得属性的名称
            String propertyName = pd.getName();
            System.out.println(propertyName);
            // 获得属性的类型
            Class type = pd.getPropertyType();
            System.out.println(type);
        }

    }

    /**
     * 操作bean的指定属性
     * 
     * @throws Exception
     */
    @Test
    public void operateAgeProperty() throws Exception {
        Student p = new Student();
        // 直接创建属性描述器对象,传入对应的参数
        PropertyDescriptor pd = new PropertyDescriptor("age", Student.class);
        // 获取它的setter方法
        Method setMethod = pd.getWriteMethod(); // setAge
        setMethod.invoke(p, 34);
        // 获取它的getter方法
        Method getMethod = pd.getReadMethod(); // getAge
        // 传入一个本类对象,并操作方法
        System.out.println(getMethod.invoke(p, null));

    }

}

至此,我们已将常见的几种通过反射获得类中字段的方法演示完毕,有不足的地方,希望大家多多提意见!






以上是关于Java内省的主要内容,如果未能解决你的问题,请参考以下文章

java内省小记

理解Java的反射与内省及其区别

java 中反射机制和内省机制的区别是啥?

java----内省

Java内省详解

java学习之内省