内省是Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name, 那我们可以通过getName,setName来得到其值或者设置新的值。通过getName/setName来访问name属性,这就是默认的规则。Java中提供了一套API用来访问某个属性的getter/setter法,通过这些API可以使你不需要了解这个规则,这些API存放于包java.beans中。
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:
Student.java代码清单:
public class Student {
private String name; //字段
rivate String sex;
private int age;
private String email;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void setXxx(){ //写方法
}
public String getXxx(){ //读方法
return "xxx";
}
}
StudentTest.java代码清单:
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 StudentTest {
@Test
public void test() throws IntrospectionException,
IllegalArgumentException,IllegalAccessException,
InvocationTargetException {
Student st = new Student();
// 1、通过Introspector类获得Bean对象的 BeanInfo
BeanInfo entity = Introspector.getBeanInfo(Student.class);
// 2、然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor)
PropertyDescriptor pdrs[] = entity.getPropertyDescriptors();
// 3、通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法
for (PropertyDescriptor pd : pdrs) {
// System.out.println(pd.getName());
/*
* System.out.println(pd.getShortDescription());
* System.out.println(pd.getDisplayName());
*/
/*if (pd.getName().equals("age")) { //age是什么类型?
Method md = pd.getWriteMethod();
md.invoke(st, 12);
}
*/
//获取属性的类型
System.out.println(pd.getName()+" "+pd.getPropertyType());
}
//System.out.println(st.getAge());
}
//简便的方法
@Test
public void test1()throws Exception{
Student st = new Student();
//通过构造器 创建 PropertyDescriptor对象
PropertyDescriptor pd = new PropertyDescriptor("age", Student.class);
Method md = pd.getWriteMethod(); //写操作
md.invoke(st, 120);
System.out.println(st.getAge());
md = pd.getReadMethod();
int value = (Integer)md.invoke(st, null); //读操作
System.out.println(value);
}
//apache beanutils工具包
}
Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils。
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
下面通过一个案例来了解BeanUtils类的使用。
Student.java代码清单:
import java.util.Date;
public class Student {
private String name;
private int age;
private Date birthday;
public String getName() { //读方法
return name;
}
public void setName(String name) { //写方法
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;
public class Demo01 {
/* 采用BeanUtils为Student 的name属性赋值 */
@Test
public void test1() throws Exception {
// 1、加载Class文件
Class cls = Class.forName("cn.csdn.beanutils.Student");
// 2、创建bean对象
Student bean = (Student)cls.newInstance();
// 3、采用BeanUtils对name属性赋值
BeanUtils.setProperty(bean, "name", "xxx");
//String value = BeanUtils.getProperty(bean, "name");
System.out.println(value);
}
/* Beanutils支持基本数据类型的自动转换 */
@Test
public void test2() throws Exception {
// 1、定义class文件
String className = "cn.csdn.beanutils.Student";
// 2、定义操作的属性
String name = "age";
// 3、创建class对象
Class cls = Class.forName(className);
// 4、创建bean对象
Student bean = (Student) cls.newInstance();
// 5、为操作的bean对象的name属性赋值
BeanUtils.setProperty(bean, name, "200");
// 6、执行输出
System.out.println(bean.getAge());
}
@Test
public void test3() throws IllegalAccessException,InvocationTargetException {
Student st = new Student();
BeanUtils.setProperty(st, "name", "redarmy"); // 避免了基本的数据类型转换的问题
System.out.println(st.getName());
}
@Test
public void test4() throws Exception {
Student bean = new Student();
BeanUtils.setProperty(bean, "birthday", new Date());
System.out.println(bean.getBirthday());
}
@Test
public void test5() throws Exception {
Student bean = new Student();
// 自带的转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.setProperty(bean, "birthday", "1997-12-12");
System.out.println(bean.getBirthday());
}
@Test
public void test6() throws Exception {
Student bean = new Student();
//自定义转换器
ConvertUtils.register(new Converter() {
// 转换的类型 //转换的值
public Object convert(Class type, Object value) {
if (value == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dt = null;
try {
dt = sdf.parse((String) value);
} catch (ParseException e) {
throw new ConversionException("日期格式转换有问题....");
}
return dt;
}}, Date.class);
BeanUtils.setProperty(bean, "birthday", "1997-11-12");
System.out.println(bean.getBirthday()); //toString()
}
}
将Java的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性。有很多项目都是采取这两种技术来实现其核心功能,例如我们前面提到的Struts,还有用于处理XML文件的Digester项目,其实应该说几乎所有的项目都或多或少的采用这两种技术。在实际应用过程中二者要相互结合方能发挥真正的智能化以及高度可扩展性。
分享到:
相关推荐
特别详细的java内省思维导图,全方面介绍java内省的功能以及用法用处。
JAVA 的内省机制(introspector)和反射机制(reflection)是两个重要的概念,在 JAVA 编程中扮演着至关重要的角色。那么,什么是内省机制和反射机制?它们有什么区别和联系? 一、内省机制(introspector) 内省...
### Java中的内省与反射详解 #### 一、引言 在深入了解Java语言的过程中,我们会遇到两个重要的概念:反射和内省。这两种技术在实际开发中有着广泛的应用,尤其是在需要进行动态操作或元数据处理的场景下尤为重要...
Java反射与内省是Java编程语言中的核心特性,它们为开发者提供了强大的能力,可以在运行时检查和操作类、接口、对象及其属性。本PPT深入探讨了这些概念,旨在帮助开发者充分利用Java平台的灵活性。 首先,Java反射...
Java内省(Introspector)是Java语言提供的一种机制,用于在运行时分析Java对象的属性、方法和事件。这个特性对于开发人员来说非常有用,因为它允许程序动态地检查和修改对象的状态,而不必了解对象的具体实现细节。...
内省在Java中是通过java.beans包中的类来实现的,主要用于获取类的信息,如属性、方法等。在实现IOC时,内省可以用来动态地读取配置文件,了解对象的依赖关系,然后根据这些信息实例化和装配对象。例如,我们可以...
在IT领域,特别是Java编程中,递归获取所有超类以及内省获取所有属性和getter、setter方法是两个重要的概念。这些技术对于理解和操作Java对象的结构和行为至关重要。让我们详细探讨这两个主题。 首先,我们来看递归...
Java内省在JavaEE开发中扮演着重要角色,尤其是在持久化、数据绑定、视图渲染等场景中。例如,Struts和Spring框架都大量使用了内省来实现MVC模式中的模型与视图之间的数据交换。通过内省,开发者可以轻松地实现对...
java 反射机制全解 java 反射机制是 Java 语言中的一种动态获取信息和调用对象方法的技术...内省是 Java 语言中的一种机制,用于获取对象的信息和调用对象的方法。反射机制可以动态地获取内省的信息和调用内省的方法。
1. `commons-beanutils-1.9.2.jar`:这是Apache Commons BeanUtils库的一个版本,它是对Java内省功能的一个扩展和封装。BeanUtils库提供了一种简单的方式来操作JavaBeans,即具有getter和setter方法的对象。它简化了...
在Java编程中,Spring框架是应用最广泛的IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)容器之一。本篇文章将深入探讨如何利用反射和内省技术来实现一个简单的Spring IOC。首先,...
10. **内省(Introspection)**:Java API提供了java.lang.reflect包,允许在运行时检查类、接口和对象的信息,如方法、构造器和字段。 通过查阅"API 5.0中文.chm"文件,你可以详细了解到这些特性和更多其他功能,...
深入学习这些源代码,可以帮助读者掌握Java的高级特性和最佳实践,如模块系统、反射、注解、枚举、内省等。此外,还可以通过阅读和分析这些代码来提升对设计模式和面向对象设计原则的理解。总之,《JAVA核心技术-卷...
`Introspector` 是Java内省的核心类,它提供了一系列的方法来获取关于JavaBean的信息。例如,`Introspector.getBeanInfo(Class)` 方法可以获取指定类的BeanInfo,这包含了关于类的属性(PropertyDescriptor)、事件...
在Java面试中,经常会出现与反射机制相关的题目。这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 ...
除此之外,你还可以期待看到输入输出流、反射、注解、枚举、枚举类型、内省、动态代理等高级Java特性的源代码示例。这些内容将帮助你提升到更高级的Java编程水平。 总之,这份《Thinking in Java 4》的源码是一个...
Java API 1.5,也被称为Java SE 5.0(Java Standard Edition 5.0),是Java发展历程中的一个重要里程碑,引入了许多创新特性和改进,为开发者提供了更强大的工具和功能。这个API文档包含了Java语言的全面参考资料,...
随着Java的不断发展,第二版规范(JLS 2nd Edition)涵盖了Java 1.1和1.2的主要更新,包括集合框架的引入、内省(Introspection)能力的增强、反射(Reflection)API的完善,以及新的I/O流和网络编程API。...
Java 5.0,也被称为Java 2 Platform Standard Edition (J2SE) 5.0,是Java发展历程中的一个重要里程碑,引入了许多创新特性,极大地提升了开发效率和代码质量。这份"Java5.0中方帮助文档"是针对中国开发者量身定制的...
读者可以通过本书了解到反射在执行内省、代理对象创建、类加载等操作时,那些在日常Java程序中常常可见但解释不足的底层原理。 此外,本书克服了反射作为一门神秘且复杂的哲学追求的名声,将其作为创建高级应用不可...