Java内省实例解析

图像中轮廓的个数,里面vector的size代表了轮廓上点的个数。了解JavaBean

内省对应的英文单词为IntroSpector,它主要用于对JavaBean进行操作,JavaBean是一种特殊的Java类,其中的某些方法符合某种命名规则,如果一个Java类中的一些方法符合某种命名规则,则可以把它当作JavaBean来使用。

JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(ValueObject,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。

例如:

setId()的属性名-->id

isLast()的属性名-->last

setCPU的属性名是什么?-->CPU

getUPS的属性名是什么?-->UPS

总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:

在JavaEE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!

JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?用内省这套api操作JavaBean比用普通类的方式更方便。

对JavaBean的简单内省操作

主要用到了java.beans.PropertyDescriptor类,用来得到某个Class对象属性集中的某个JavaBean属性,然后调用getReadMethod()、getWriteMethod()方法获得相应的get、set方法。

代码示例:

Domain类:

[cpp]viewplaincopy

intmain()

package ustc.lichunchun.bean;
import java.util.Date;
public class ReflectPoint {
  private Date birthday = new Date();
private int x;
public int y;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
public ReflectPoint(int x, int y) {
	super();
	this.x = x;
	this.y = y;
}
@Override
  public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + x;
	result = prime * result + y;
	return result;
}
@Override
  public Boolean equals(Object obj) {
	if (this == obj)
	      return true;
	if (obj == null)
	      return false;
	if (getClass() != obj.getClass())
	      return false;
	final ReflectPoint other = (ReflectPoint) obj;
	if (x != other.x)
	      return false;
	if (y != other.y)
	      return false;
	return true;
}
@Override
  public String toString(){
	return str1 + ":" + str2 + ":" + str3;
}
public int getX() {
	return x;
}
public void setX(int x) {
	this.x = x;
}
public int getY() {
	return y;
}
public void setY(int y) {
	this.y = y;
}
public Date getBirthday() {
	return birthday;
}
public void setBirthday(Date birthday) {
	this.birthday = birthday;
}
}

简单内省操作:

package ustc.lichunchun.bean;
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;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX-->
		getProperty(pt1, propertyName);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(pt1.getX());
	}
	private static void setProperty(Object pt1, String propertyName, Object value)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodGetX = pd.getReadMethod();
		methodGetX.invoke(pt1);
	}
}

对JavaBean的复杂内省操作

采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。

复杂内省操作:

package ustc.lichunchun.bean;
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;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX-->
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(pt1.getX());
	}
	private static void setProperty(Object pt1, String propertyName, Object value)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		/*
    PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
    Method methodGetX = pd.getReadMethod();
    methodGetX.invoke(pt1);
    */
		BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal = null;
		for (PropertyDescriptor pd : pds){
			if(pd.getName().equals(propertyName)){
				Method methodGetX = pd.getReadMethod();
				retVal = methodGetX.invoke(pt1);
				break;
			}
		}
		return retVal;
	}
}

使用BeanUtils工具包操作JavaBean

在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。

用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。

注意:用这两个类之前,需要在eclipse工程的lib文件夹中导入commons-beanutils.jar、commons-logging-1.1.jar两个jar包,并且AddtoBuildPath。

代码示例:

package ustc.lichunchun.bean;
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.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX-->
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
		//String
		BeanUtils.setProperty(pt1, "x", "9");
		System.out.println(pt1.getX());
		/*
    Map map = {name:"zxx",age:18};//java7的新特性
    BeanUtils.setProperty(map, "name", "lcc");
    */
		BeanUtils.setProperty(pt1, "birthday.time", "111");
		//支持属性链
		System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
		PropertyUtils.setProperty(pt1, "x", 23);
		System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
		//Integer
		/*
    BeanUtils和PropertyUtils的区别:
    BeanUtils以字符串形式对JavaBean进行操作,也可以操作Map类,并且可以讲JavaBean和Map进行互相转换(describe、populate)
    PropertyUtils以JavaBean属性本身的数据类型进行操作
     */
	}
	private static void setProperty(Object pt1, String propertyName, Object value)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName)
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		/*
    PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
    Method methodGetX = pd.getReadMethod();
    methodGetX.invoke(pt1);
    */
		BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal = null;
		for (PropertyDescriptor pd : pds){
			if(pd.getName().equals(propertyName)){
				Method methodGetX = pd.getReadMethod();
				retVal = methodGetX.invoke(pt1);
				break;
			}
		}
		return retVal;
	}
}

总结

以上就是本文关于Java内省实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

您可能感兴趣的文章:

  • java中用ObjectMapper类实现Json与bean的转换示例
  • 详谈JSON与Javabean转换的几种形式
  • Javabean和map相互转化方法代码示例
  • Java之Spring注解配置bean实例代码解析
  • JavaBean四个作用域范围的详解
  • Spring装配Bean之用Java代码安装配置bean详解
  • 基于JavaBean编辑器读取peroperties文件的实例
  • FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换操作
(0)

相关推荐

  • Java之Spring注解配置bean实例代码解析

    前面几篇均是使用xml配置bean,如果有上百个bean,这是不可想象的.故而,请使用注解配置bean !!! [1]注解类别 @Component : 基本注解, 标识了一个受 Spring(点击这里可以下载<Spring应用开发完全手册>) 管理的组件 @Repository : 标识持久层组件 @Service : 标识服务层(业务层)组件 @Controller : 标识表现层组件 Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 对于扫描到的组

  • java中用ObjectMapper类实现Json与bean的转换示例

    前言 ObjectMapper是jackson中的方法,本文主要给大家介绍了关于java中用ObjectMapper类实现Json与bean转换的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.将json字符串转为bean public class JsonToJavaBean { public static void main(String[] args) { String str="{\"student\":[{\"name\&q

  • Spring装配Bean之用Java代码安装配置bean详解

    前言 本文主要给大家介绍了关于Spring之利用Java代码安装配置bean的相关内容,尽管通过组件扫描和自动装配实现Spring的自动化配置很方便也推荐,但是有时候自动配置的方式实现不了,就需要明确显示的配置Spring.比如说,想要将第三方库中的组件装配到自己的应用中,这样的情况下,是没办法在它的类上添加 @Compnent和 @Autowired注解的. 在这种情况下,需要使用显示装配的方式,可以分别通过Java和XML实现,推荐使用Java的方式,因为更加强大,类型安全并且重构友好,因为

  • JavaBean四个作用域范围的详解

    JavaBean四个作用域范围的详解 一 说明 使用useBeans的scope属性可以用来指定javabean的作用范围. 二 四个作用范围 三 代码 1.login.jsp <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" %> <% String path = request.getContextPath

  • 详谈JSON与Javabean转换的几种形式

    JSON格式的数据传递是最常用的方法之一,以下列出了常用的几种形态以及与Javabean之间的转换: String json1="{'name':'zhangsan','age':23,'interests':[{'interest':'篮球','colors':['绿色','黄色']},{'interest':'足球','colors':['红色','蓝色']}]}"; String json2="[{'name':'zhangsan'},{'name':'lisi'},{

  • Javabean和map相互转化方法代码示例

    在做导入的时候,遇到了需要将map对象转化 成javabean的问题,也就是说,不清楚javabean的内部字段排列,只知道map的 key代表javabean的字段名,value代表值. 那现在就需要用转化工具了.是通用的哦! 首先来看 JavaBean 转化成Map的方法: [java] /** * 将一个 JavaBean 对象转化为一个 Map * @param bean 要转化的JavaBean 对象 * @return 转化出来的 Map 对象 * @throws Introspec

  • 基于JavaBean编辑器读取peroperties文件的实例

    引言 最近在重读<精通Spring+4.x++企业应用开发实战>这本书,看到了有关JavaBean编辑器的部分,了解到PropertyEditor和BeanInfo的使用.不得不说,BeanInfo是一个很强大的东西,Java中的内省也与之有一点点小关联. JavaBean.PropertyEditor与BeanInfo JavaBean简单介绍 JavaBean是一种Java写成的可重用组件,本质上还是一个Java类,但是与一般的Java类不同,JavaBean必须有一个无参的构造函数,其字

  • FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换操作

    fastJson对于json格式字符串的解析主要用到了一下三个类: JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换. JSONObject:fastJson提供的json对象. JSONArray:fastJson提供json数组对象. 我们可以把JSONObject当成一个Map<String,Object>来看,只是JSONObject提供了更为丰富便捷的方法,方便我们对于对象属性的操作.我们看一下源码. 同样我们可以把JSONArra

  • Java内省实例解析

    图像中轮廓的个数,里面vector的size代表了轮廓上点的个数.了解JavaBean 内省对应的英文单词为IntroSpector,它主要用于对JavaBean进行操作,JavaBean是一种特殊的Java类,其中的某些方法符合某种命名规则,如果一个Java类中的一些方法符合某种命名规则,则可以把它当作JavaBean来使用. JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则. 如果要在两个模块之间传递多个信息

  • Java 代码实例解析设计模式之监听者模式

    代码展示 Main:测试类 ObServer:每个被监听的对象实现该接口,重写该方法,完成自己的业务 public interface ObServer { /** * 当某一个被监控的对象发生变化时 * 所有实现该方法处理方法 */ void exceptionHandler(); } Subject:监听者容器 public interface Subject { /** * 添加被观察对象 */ void add(ObServer obServer); /** * 通知所有被观察者完成自己

  • Java多线程 实例解析

    Java多线程实例 3种实现方法 Java中的多线程有三种实现方式: 1.继承Thread类,重写run方法.Thread本质上也是一个实现了Runnable的实例,他代表一个线程的实例,并且启动线程的唯一方法就是通过Thread类的start方法. 2.实现Runnable接口,并实现该接口的run()方法.创建一个Thread对象,用实现的Runnable接口的对象作为参数实例化Thread对象,调用此对象的start方法. 3.实现Callable接口,重写call方法.Callable接

  • Java Web开发入门书籍实例解析(总结一)

    从事Java Web开发这一段时间来,对Java 面向对象的思想和MVC开发模式可以说已经熟悉了.我当前参与的项目使用的框架是Spring.SpringMVC.Hibernate.下面我们小编给大家整理一篇教程帮助大家学习javaweb相关知识,感兴趣的朋友可以参考下. 一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 1.静态web资源(如html 页面):指w

  • Java编程探索之泛型擦除实例解析

    1.问题引出 源码: public static void main(String[] args) { List<Integer> a = new ArrayList<Integer>(); List<String> b = new ArrayList<String>(); System.out.println(a.getClass() == b.getClass());//结果true } 编译后L public static void main(Stri

  • Java对象的XML序列化与反序列化实例解析

    上一篇文章我们介绍了java实现的各种排序算法代码示例,本文我们看看Java对象的xml序列化与反序列化的相关内容,具体如下. XML是一种标准的数据交换规范,可以方便地用于在应用之间交换各类数据.如果能在Java对象和XML文档之间建立某种映射,例如Java对象的XML序列化和反序列化,那么就可以使Java的对象方便地与其他应用进行交换. java.beans包里面有两个类XMLEncoder和Decoder,分别用于将符合JabaBeans规范的Java对象以XML方式序列化和反序列化.以下

  • Java数组越界问题实例解析

    Java中数组初始化和OC其实是一样的,分为动态初始化和静态初始化, 动态初始化:指定长度,由系统给出初始化值 静态初始化:给出初始化值,由系统给出长度 在我们使用数组时最容易出现的就是数组越界问题,好了,这里有个简单的例子 int [][] array = {{1,2,3},{1,4}}; System.out.println(array[1][2]); 这是一个二维数组,很明显,数组越界了,控制台中会打印如下信息: Exception in thread "main" java.l

  • 实例解析Java中的构造器初始化

    1.初始化顺序 当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序开始对这些实例属性执行初始化,其初始化顺序是:先执行初始化块或声明属性时制定的初始值,再执行构造器里制定的初始值. 在类的内部,变量定义的先后顺序决定了初始化的顺序,即时变量散布于方法定义之间,它们仍就会在任何方法(包括构造器)被调用之前得到初始化. class Window { Window(int maker) { System.out.println("Window(&quo

  • Java用POI解析excel并获取所有单元格数据的实例

    1.导入POI相关jar包 org.apache.poi jar 2.代码示例 public List getAllExcel(File file, String tableName, String fname, String enterpriseId, String reportId, String projectId) throws FileNotFoundException, IOException, ClassNotFoundException, InstantiationExcepti

  • Java面向对象编程(封装/继承/多态)实例解析

    本文主要介绍了面向对象的三大特征实例解析,下面看看具体内容. 封装 封装一个Teacher和Student类 package com.hz.test; public class Teacher { private String name; private String majorDirection; private String teachCourse; private int teachAge; public Teacher() { super(); } public Teacher(Stri

随机推荐