Java内省
什么是内省?
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内省的更多相关文章
- JAVA内省(Introspector)
什么是Java内省:内省是Java语言对Bean类属性.事件的一种缺省处理方法. Java内省的作用:一般在开发框架时,当需要操作一个JavaBean时,如果一直用反射来操作,显得很麻烦:所以sun公 ...
- java 内省
用内省来操作Bean会给程序带来很大的便利,特别是在很大的实体对象的时候,在其属性很多的时候要为其赋值的时候, package com.bean; public class User { privat ...
- Java内省机制
转自: https://blog.csdn.net/hahalzb/article/details/5972421 1.java内省机制其实通俗的理解为,对自身的进行一个扫描,这个扫描的对象就是我们普 ...
- Java 内省(Introspector)深入理解
Java 内省(Introspector)深入理解 一些概念: 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类 ...
- 【小家Spring】Spring IoC是如何使用BeanWrapper和Java内省结合起来给Bean属性赋值的
#### 每篇一句 > 具备了技术深度,遇到问题可以快速定位并从根本上解决.有了技术深度之后,学习其它技术可以更快,再深入其它技术也就不会害怕 #### 相关阅读 [[小家Spring]聊聊Sp ...
- Java 内省(Introspector)和 BeanUtils
人生若只如初见,何事秋风悲画扇. 概述 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息, ...
- Java基础扫盲系列(三)— Java内省技术
前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...
- java内省机制及PropertyUtils使用方法
背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...
- java内省机制Introspector
访问JavaBean属性的两种方式 1)直接调用bean的setXXX或getXXX方法: 2)通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式: a)通过P ...
随机推荐
- mysql之多表查询
今天在项目中遇到一个数据库查询的问题:三张表分别放置不同的东西:分享的音频相关数据.分享的文字图片说说.分享的主题相关数据.所有分享的东西都可看做新鲜事,现在要求从这三张表将相同的几个字段的数据全部查 ...
- ScrollBox 响应鼠标滚轮和ComboBox禁止滚动
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: ...
- Spark Streaming揭秘 Day35 Spark core思考
Spark Streaming揭秘 Day35 Spark core思考 Spark上的子框架,都是后来加上去的.都是在Spark core上完成的,所有框架一切的实现最终还是由Spark core来 ...
- sqlplus连接数据库的4种方式
本文对sqlplus连接数据库的几种方式进行大概介绍 下面是我的tnsnames.ora相关信息: /opt/oracle/product/10.1.0/db_1/network/admin/tnsn ...
- OnDrawGizmos函数
如果你想绘制可被点选的gizmos,执行这个函数. 这允许你在场景中快速选择重要的物体. 注意: OnDrawGizmos使用相对鼠标坐标 using UnityEngine; using Syste ...
- SRM 616 ColorfulCoins
题意:给定一个从小到大的货币面值,每一个面额都是其前面面额的倍数(倍数大于等于2),每一种货币面值对应一种颜色,目前不清楚面值与颜色的对应关系.要求用最少的查询次数来确定面额与颜色的对应关系.(一次查 ...
- SVN备份教程(二)
上次的博文中SVN备份教程(一)我们简单介绍了一下SVN备份是如何操作的,今天我们接着将上次的问题进行优化. 1.问题回顾 在讲之前,我们先来将上次的问题重申一下.之前的SVN备份存在的问题很简单,每 ...
- centos7初步配置
centos7初步配置 首先安装lrzsz zip/unzip yum -y install lrzsz yum -y install zip unzip 安装vim yum install vim* ...
- 2733: [HNOI2012]永无乡 - BZOJ
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- [转载]面向对象设计(OOD)思想(C#)
有了思想才能飞翔,缺乏灵活就象少了轮子的汽车,难以飞奔.为了更好的理解设计思想,结合一个尽可能简洁的实例来说明OOD.设计模式及重构.通过下面的代码,详细地阐述面向对象设计思想. 一.传统过程化设计思 ...