JAVA基础 内省机制

原创 2016年08月31日 06:31:28

注:本文主要记录自 兄弟连_马剑威 JavaSE第三季 第49讲 内省机制

1、JavaBean的概念

  • 什么是JavaBean?
  • Bean理解为组件的意思,JavaBean就是Java组件,在广泛的理解就是一个类,对于组件来说,关键在于要具有“能够被IDE构建工具侦测其属性和事件”的能力,通常在Java中
一个JavaBean要具备这样的命名规则:
  1. 对于一个名称为xxx的属性,通常你要写两个方法:getXxx() 和 setXxx() .任何浏览这些方法的工具,都会把get或set后面的第一个字母自动转换为小写。
  2. 对于布尔型属性,可以使用以上get和set方式,不过也可以把get替换成is
  3. Bean的普通方法不必遵循以上命名规则,不过他们必须是public的
  4. 对于事件,要使用Swing中处理监听器的方式。如addWindowListener,removeWindowListener
2、内省的基本概念
  • 内省(IntroSpector)是Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。
  • 通过getName/setName来访问name属性,这就是默认的规则。
  • Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要理解这个规则,这些API存放于包java.beans中,一般的做法是通过类Introspector的getBeanInfo方法来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。

3、IntroSpector相关API
1、Introspector类:
Introspector类为通过工具学习有关受目标JavaBean支持的属性、事件和方法的知识提供了一个标准方法。
static BeanInfo getBeanInfo(Class<?> beanClass)
在JavaBean上进行反省,了解其所有属性、公开的方法和事件

2、BeanInfo类
该类实现此BeanInfo接口并提供有关其bean的方法、属性、事件等显式信息。
MethodDescriptor[] getMethodDescriptors()
获得 beans MethodDescriptor
PropertyDescriptor[] getPropertyDescriptors()
获得beans PropertyDescriptors

3、PropertyDescriptor类:
PropertyDescriptor描述JavaBean通过一对存储器方法导出的一个属性
Method getReadMethod()
获得应该用于读取属性值的方法
Method getWriteMethod()
获得应该用于写入属性值的方法 

4、MethodDescriptor类:
MethodDescriptor 描述了一种特殊方法
即Java Bean支持从其他组件对其进行外部访问
Method getMethod()
获得此MethodDescriptor封装的方法

实例:
/**
 * javaBean
 *
 */
public class Dog {
	private int age;
	private String name;

	public int getAge() {
		return age;
	}

	public String getName() {
		return name;
	}

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

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

}

/**
 * 内省
 *
 */
public class IntroSpectorDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		Dog dog=new Dog();//使用者与被使用者耦合
		//不耦合可以使用工厂模式
		Dog dog=DogFactory.getDog("dog");
		
	}

}

/**
 * 工厂类
 *
 */
public class DogFactory {
	public static Dog getDog(String dogname) {
		if("dog".equals(dogname)){
			return  new Dog();//此处也耦合
		}
		return null;
	}
}

但在如上的工厂类里,仍是会用到  new Dog();产生耦合
所以需要采取另外的途径,
如在反射中的:Class.forName("class的全路径")

创建配置文件 bean.properties,使用配置文件的目的是修改方便,相比定义在类中的静态参数而言,当某天代码参数发生变化时,只要修改配置文件中的参数,重启系统即可。而在代码中的参数修改则需要重新修改源码,编译,替换。【注:配置文件如果要正常显示中文,需要将配置文件的编码格式更改为:utf-8】
<pre name="code" class="java">#配置javaBean的全名
dog=IntroSpectorDemo.Dog
dog.name=小白
dog.age=4

在工厂类中通过读取配置文件信息,并利用内省机制生成Dog实例
/**
 * 工厂类
 * @author zhan414
 *
 */
public class DogFactory {
	
	private static Properties config=new Properties();//处理properties文件的工具类,负责读写属性文件
	static{
		//读取属性文件
		InputStream inputStream=Thread.currentThread().getContextClassLoader().getResourceAsStream("bean.properties");
		//加载属性文件
		try {
			config.load(inputStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static Dog getDog(String dogname){
		//从Properties对象中根据key获取value
		String className =config.getProperty("dog");
		try {
			//根据类全名获取类信息对象Class对象
			Class dogClass = Class.forName(className);
			//实例化对象
			Dog dog=(Dog) dogClass.newInstance();
			//内省:获取bean信息
			BeanInfo beanInfo=Introspector.getBeanInfo(dogClass);
			//通过bean信息获取所有属性描述器,数组
			PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
			//循环遍历属性描述器
			for (PropertyDescriptor propertyDescriptor : pds) {
				if ("name".equals(propertyDescriptor.getName())) {//判断是否是name属性
					String nameValue=config.getProperty("dog.name");
					//通过属性描述器获取该属性的写操作(set方法)
					Method method=propertyDescriptor.getWriteMethod();
					//在dog对象上调用方法
					method.invoke(dog, nameValue);
				}else if ("age".equals(propertyDescriptor.getName())) {
					String  ageValue=config.getProperty("dog.age");
					Method method=propertyDescriptor.getWriteMethod();//内省
					method.invoke(dog, Integer.valueOf(ageValue));
				}
				//返回对某属性的method对象,相比反射要方便许多
				//eg:Method setNameMethod=personClass4.getMethod("setName", String.class);  
			    //	 setNameMethod.invoke(p5, "小花");//相当于 p5.setName("小花");  
			}
			return dog;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
测试:
public class IntroSpectorDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Dog dog=DogFactory.getDog("dog");
		System.out.println("dog.name= "+dog.getName()+" , dog.age= "+dog.getAge());
	}
}
输出:
dog.name= å°ç½ , dog.age= 4
可以看到name为乱码,这是因为配置文件中 dog.name的值为中文,未转成 unicode格式
解决方法:修改DogFactory中的properties文件输入静态块,配置输入流的编码格式,如下:
	static {
		try {
			// 读取属性文件
			InputStream inputStream = Thread.currentThread()
					.getContextClassLoader()
					.getResourceAsStream("bean.properties");
			BufferedReader bf = new BufferedReader(new InputStreamReader(
					inputStream, "utf-8"));
			// 加载属性文件
			config.load(bf);
			//关闭流
			inputStream.close();
			bf.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
修改后便可输出中文







eclipse properties文件中文格式使用配置:




版权声明:本文为博主原创文章,未经博主允许不得转载。

Java内省机制小总结

Java内省机制小总结 Java中的反射机制是通过名称得到类的方法和对象的成份,对于一切Java类都是适用的,但是有时候使用起来比较麻烦。而JavaBean是一种特殊的Java类,遵守JavaBean...
  • changqianger
  • changqianger
  • 2015年04月28日 20:32
  • 857

JAVA的内省机制(introspector)与反射机制(reflection)

 相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术,这种技术比内省机制使用范围更广泛。例如我们可以通过类名来生成一个类的实...
  • zgmzyr
  • zgmzyr
  • 2010年07月21日 17:19
  • 4431

Java读书笔记十一(Java中的内省机制)

1.前言 最近在学习Java的时候,突然发现了这个概念,鉴于好奇心的压迫,于是打算写一篇博客来总结一下。  2.什么是内省机制 为了让程序员们更好的从左Java对象的属性,SUN公司开发了一...
  • ZHOUCHAOQIANG
  • ZHOUCHAOQIANG
  • 2015年08月04日 11:53
  • 1583

内省 + 反射(简单应用实现原理)

当我们需要封装从页面传递到后台的请求参数时,简单的方式就是使用一个工具类帮我们封装,省很多力气,还不容易出错。那接下来就简单介绍下这个BeanUtils工具类的实现原理,顺便重温下java内省机制。 ...
  • java__project
  • java__project
  • 2016年12月24日 22:55
  • 565

Python 学习积累《二》 Python的内省机制

Python的内省机制还是比较强大的。所谓内省,实际上主要是指在runtime获得一个对象的全部类型信息。这样可以提供更好的编程灵活性。 Java中的introspection是通过Reflecti...
  • achang21
  • achang21
  • 2011年09月20日 13:42
  • 3336

Java内省详解

内省的解释内省在wiki上的解释: 在计算机科学中,内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。...
  • u014394715
  • u014394715
  • 2016年04月22日 10:19
  • 5364

[Python]回顾Python中的内省机制

学习资源http://zetcode.com/lang/python/introspection/ http://www.ibm.com/developerworks/library/l-pyint...
  • slowlight93
  • slowlight93
  • 2016年02月13日 19:21
  • 1559

JAVA Introspector内省用法

package cn.itcat.introspector; import java.beans.BeanInfo; import java.beans.Introspector; import ja...
  • dlj949611520
  • dlj949611520
  • 2016年04月15日 20:24
  • 598

Java 基础加强 - JavaBean与内省操作

Java基础加强JavaBean与内省操作 一.JavaBean 1.     什么叫做JavaBean? JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于...
  • hua631150873
  • hua631150873
  • 2013年09月18日 22:19
  • 1540

Java的反射和内省的区别

反射 反射就是运行时获取一个类的所有信息,可以获取到.class的任何定义的信息(包括成员 变量,成员方法,构造器等) 可以操纵类的字段、方法、构造器等部分。 内省 内省基于反射实现,主要...
  • zhanjixun
  • zhanjixun
  • 2017年03月30日 00:00
  • 1468
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA基础 内省机制
举报原因:
原因补充:

(最多只允许输入30个字)