什么是内省?

  Java语言对bean类属性、事件的一种缺省处理方法,例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值

什么是JavaBean?

  JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。

下面这个Person类就是一个JavaBean,大家参考一下:

public class Person {

    private int id;
private String name; public Person() {
} public Person(int id, String name) {
this.id = id;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

  Java中提供了一套API来处理JavaBean,也就是内省(Introspector)机制的核心,这些处理类位于java.beans目录下,下面我们来了解一下:

PropertyDescriptor类:

  Introduction:可以叫这个类作属性描述类,也就是可以通过这个类去描述我们想要操作的类。

  Methods:

    public PropertyDescriptor(String propertyName, Class<?> beanClass):propertyName就是JavaBean中的属性,像上面那样Person类中的“id”,beanClass就是JavaBean类了,像Person类,我们通过getClass方法就可以拿到该类的Class了,这个构造方法得到了该JavaBean的属性描述类。

    public Method getReadMethod():获取用于读取属性值的方法,例如通过这个方法就可以拿到“id”的getId方法。

    public Method getWriteMethod():获取用于写入属性值的方法,例如通过这个方法就可以拿到“id”的setId方法。

    注意:上面两个方法的返回值是Method,要操作方法的话需要通过invoke方法来调用。

@SuppressWarnings("all")
public class TestPropertyDescriptor { private static Person person; @BeforeClass
public static void init() {
person = new Person(1, "xujianguo");
} @Test
public void testGetProperty() throws Exception {
PropertyDescriptor pd = new PropertyDescriptor("id", person.getClass());
Method method = pd.getReadMethod();
Object id = method.invoke(person, null);
System.out.println(id);
} @Test
public void testSetProperty() throws Exception {
PropertyDescriptor pd = new PropertyDescriptor("id", person.getClass());
Method method = pd.getWriteMethod();
method.invoke(person, 3);
testGetProperty();
}
}

上面的testGetProperty方法可以拿到id的值,testSetProperty方法可以设置id的值,然后通过testGetProperty方法打印出id的值。

Introspector类:

  Introduction:Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。

  Method:

    public static BeanInfo getBeanInfo(Class<?> beanClass)在javabean上进行内省,了解该类的所有属性、方法和事件,所以这个方法很重要。这个方法的返回值是BeanInfo类型的,下面我们来看看这个类:

  BeanInfo类:

    Introduction:该类是一个可以提供JavaBean各种信息的类。

    Method:

      public PropertyDescriptor[] getPropertyDescriptors():获取bean的PropertyDescriptor,这个获取的是一个数组,数组里面装的是各种属性的属性描述类,通过该方法就可以找到我们想要操作的那个方法。

@SuppressWarnings("all")
public class TestPropertyDescriptor { private static Person person; @BeforeClass
public static void init() {
person = new Person(1, "xujianguo");
} @Test
public void testOtherMethod() throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(person.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object value = null;
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals("name")) {
Method method = pd.getReadMethod();
value = method.invoke(person, null);
break;
}
}
System.out.println(value);
}
}

上面的例子在一个属性描述类的数组中找到我们要操作的name的方法,PropertyDescriptor的getName方法可以拿到属性名。

下面介绍BeanUtils工具包:

BeanUtils就是一个小小的框架,里面封装很多方法,让我们很方便的调用,随心所欲的操作JavaBean。

  BeanUtils.PropertyUtils:是这个工具包里面很重要的一个类,这个类通过它的名字就可以知道它操作的是JavaBean的属性,在操作之前我们首先理解property的几种状态:

  Simple:也就是Java的基础类型,指property的属性修饰符,如int、String,这些都是比较简单的类型,我们就可以通过public static Object getSimpleProperty(Object bean, String name)方法拿到属性值,用public static Object setSimpleProperty(Object bean, String name, Object value)设置属性值。

  Indexed:这个属性的状态是针对List等集合的,如果属性修饰符是List的话,就可以通过public static Obejct getIndexedProperty(Object bean, String name, int index)方法拿到属性值,用public static Obejct setIndexedProperty(Object bean, String name, int index, Object value)方法设置属性值。

  Mapped:这个属性的状态是针对Map集合,因为Map的里面的设置是key-value的关系,PropertyUtils类就用这个方法的key去拿Map中的value,即是通过public static Object getMappedProperty(Obejct bean, String name, String value)方法去拿key对应的value,通过public static Object setMappedProperty(Object bean, String name, String value, Object value)方法去设置key对应的value。

  Nested:这个就是用来解决比较复杂的属性问题,如你的List里面放置了Person,但你想拿出Person中的name属性,怎么办呢?就是用这个方法了,通过public static Object getNestedProperty(Object bean, String name)拿出属性值,通过public static Object setNestedProperty(Object bean, String name, Object value)去设置它的属性值,但是你会说,这个跟前面的一样啊,哈哈,是的,这个方法的特定即使在写name的值的时候可以通过“.”符号来层层拿出值,看下面的例子你就知道了。

首先定义一个JavaBean类:

@SuppressWarnings("rawtypes")
public class School {
private int id;
private String name;
private List list;
private Map map;
private List<Person> personList; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public List<Person> getPersonList() {
return personList;
}
public void setPersonList(List<Person> personList) {
this.personList = personList;
}
}

下面就是测试类了:

@SuppressWarnings("all")
public class BeanUtilsDemo { private static School school; @Before
public void initing() {
school = new School();
school.setId(1);
school.setName("gdut"); List list = new ArrayList();
list.add("first");
list.add("second");
school.setList(list); Map map = new HashMap();
map.put("xjg", "xujianguo");
map.put("zyp", "zhouyanping");
school.setMap(map); Person person = new Person(3, "RayGuo");
List<Person> personList = new ArrayList<Person>();
personList.add(person);
school.setPersonList(personList);
} @Test
public void testSimpleGetProperty() throws Exception, NoSuchMethodException {
int id = (Integer) PropertyUtils.getSimpleProperty(school, "id");
String name = (String) PropertyUtils.getSimpleProperty(school, "name");
System.out.println(id + " " + name);
} @Test
public void testSimpleSetProperty() throws Exception {
PropertyUtils.setSimpleProperty(school, "id", 2);
PropertyUtils.setSimpleProperty(school, "name", "scut");
testSimpleGetProperty();
} @Test
public void testIndexedGetProperty() throws Exception {
String str = (String) PropertyUtils.getIndexedProperty(school, "list", 1);
System.out.println(str);
} @Test
public void testIndexedSetProperty() throws Exception {
PropertyUtils.setIndexedProperty(school, "list", 1, "secondsecond");
testIndexedGetProperty();
} @Test
public void testMappedGetProperty() throws Exception {
String name = (String) PropertyUtils.getMappedProperty(school, "map", "zyp");
System.out.println(name);
} @Test
public void testMappedSetProperty() throws Exception {
PropertyUtils.setMappedProperty(school, "map", "zyp", "zypzyp");
testMappedGetProperty();
} @Test
public void testNestedGetProperty() throws Exception {
String name = (String) PropertyUtils.getNestedProperty(school, "personList[0].name");
System.out.println(name);
} @Test
public void testNestedSetProperty() throws Exception {
PropertyUtils.setNestedProperty(school, "personList[0].name", "ApplePing");
testNestedGetProperty();
}
}

  

  BasicDynaClass和BasicDynaBean:两个类是挺好用的东西来的,比如说你会遇到这种情况,从数据库拿到了一堆的数据,但是你不想写一个Class,也就是定义一个实体类,这个我们可以采用这个类了,就是动态生成一个JavaBean,用这个JavaBean来操作这些数据,存储这些数据,就不用写死一个Class了,下面我们来简单了解一下怎么用:

    DynaProperty类:从名字就可以知道了,动态属性,就是定义一个动态类有哪些属性了

      method:public DynaProperty(String name, Class type):这是构造方法,通过该构造方法就可以创建一个动态的属性了

    BasicDynaClass类:这个就是动态类了,通过这个类创建一个我们需要的动态类,在创建的时候当然要我们前面定义的动态属性加进入了。

      method:

        public BasicDynaClass(String name, Class dynaBeanClass, DynaProperty[] props):这个是它的构造方法,name是你要动态生成那个JavaBean的名字,dynaBeanClass就是指这个类的Class类型,props就是JavaBean的属性集合了。

        public DynaBean newInstance():通过这个方法就可以创建一个实例了。

    DynaBean类:动态的JavaBean

      method:

        Object set(String name, Object value):设置属性的值

        Object get(String name):得到属性的值

Demo:

@SuppressWarnings("rawtypes")
public class DynaClassDemo { @Test
public void test() throws Exception {
DynaProperty prop1 = new DynaProperty("id", Integer.class);
DynaProperty prop2 = new DynaProperty("name", String.class);
DynaProperty prop3 = new DynaProperty("map", java.util.Map.class);
DynaProperty[] prop = new DynaProperty[]{prop1, prop2, prop3}; BasicDynaClass dynaClass = new BasicDynaClass("people", null, prop);
DynaBean people = dynaClass.newInstance();
people.set("id", 1);
people.set("name", "xujianguo");
people.set("map", new HashMap()); System.out.println(people.get("id") + " " + people.get("name"));
}
}

      

      

  

Java内省的更多相关文章

  1. JAVA内省(Introspector)

    什么是Java内省:内省是Java语言对Bean类属性.事件的一种缺省处理方法. Java内省的作用:一般在开发框架时,当需要操作一个JavaBean时,如果一直用反射来操作,显得很麻烦:所以sun公 ...

  2. java 内省

    用内省来操作Bean会给程序带来很大的便利,特别是在很大的实体对象的时候,在其属性很多的时候要为其赋值的时候, package com.bean; public class User { privat ...

  3. Java内省机制

    转自: https://blog.csdn.net/hahalzb/article/details/5972421 1.java内省机制其实通俗的理解为,对自身的进行一个扫描,这个扫描的对象就是我们普 ...

  4. Java 内省(Introspector)深入理解

    Java 内省(Introspector)深入理解 一些概念: 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类 ...

  5. 【小家Spring】Spring IoC是如何使用BeanWrapper和Java内省结合起来给Bean属性赋值的

    #### 每篇一句 > 具备了技术深度,遇到问题可以快速定位并从根本上解决.有了技术深度之后,学习其它技术可以更快,再深入其它技术也就不会害怕 #### 相关阅读 [[小家Spring]聊聊Sp ...

  6. Java 内省(Introspector)和 BeanUtils

    人生若只如初见,何事秋风悲画扇. 概述 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息, ...

  7. Java基础扫盲系列(三)— Java内省技术

    前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...

  8. java内省机制及PropertyUtils使用方法

    背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...

  9. java内省机制Introspector

    访问JavaBean属性的两种方式 1)直接调用bean的setXXX或getXXX方法: 2)通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式: a)通过P ...

随机推荐

  1. [Oracle]Oracle学习小结(1)

    1.查看Oracle数据库中的所有用户: (1)使用具有DBA权限的账户登录数据库: (2)执行select username from dba_users. SQL> conn sys 输入口 ...

  2. 2015年1月最新中国行政区划县及以上代码mysql数据库

    中华人民共和国国家统计局>> 行政区划代码>>mysql数据格式 截图如下 行政区划mysql数据库文件下载:nation.zip 转载:http://www.sdhack.c ...

  3. 解决CxGrid Filter 后,通过 Dataset 循环时得出的结果与 Grid显示不同步的问题.

    // 方案1: 强制cxgrid 使用 dataset的 Filter GridMaster.DataController.Filter.AutoDataSetFilter := True; /// ...

  4. C++数据类型总结

    关键字:C++, 数据类型, VS2015. OS:Windows 10. ANSI C/C++基本数据类型: Type Size 数值范围 无值型void 0 byte 无值域 布尔型bool 1 ...

  5. 【转】How to view word document in WPF application

    How to view word document in WPF application (CSVSTOViewWordInWPF) Introduction The Sample demonstra ...

  6. 监听EditText

    0.得到焦点的时候,作一些处理 public class AbcActivity extends Activity implements OnFocusChangeListener{ @Overrid ...

  7. C#时间戳与时间互转

    /// <summary> /// 时间戳转成时间类型 /// </summary> /// <param name="timeStamp">& ...

  8. WPF常用数据绑定控件集合

    1.怎么用ListView控件把XML中的数据在界面上显示出来? <?xml version="1.0" encoding="utf-8" ?> & ...

  9. PlayerPrefs存储数据在本地的存储位置

    PlayerPrefs存储数据时,其在windows的存储路径是注册表: HKEY_CURRENT_USER Software CompanyName ProjectName 其中的CompanyNa ...

  10. xx创新论坛返工友情项目总结

    友情项目,顾名思义就不是我做的,只是处于友情帮别人改改别人的代码帮别人找找bug...之所以要强调这一点是因为里面的低级问题太多,实在是不好意思承认自己和这个项目有关系.. 整个过程还是挺辛苦的,毕竟 ...