概念javabean在实际编程中,我们常常需要一些用来包装值对象的类,例如student、 employee、order,这些 类中往往没有业务方法,只是为了把需要处理的实体对象进行封装,有这样的特征:
属性都是私有的;
有无参的public构造方法;
对私有属性根据需要提供公有的getxxx方法以及setxxx方法;
比如:属性名称为name,则有getname方法返回属性name值, setname方法设置name值;注意方法的名称通常是get或 set加上属性名称,并把属性名称的首字母大写;这些方法称为getters/setters;getters必须有返回值没有方法参数; setter值没有返回值,有方法参数;
例如下面的例子:
符合这些特征的类,被称为javabean;
内省内省(inspector)机制就是基于反射的基础, java语言对bean类属性、事件的一种缺省处理方法。
只要类中有getxxx方法,或者setxxx方法,或者同时有getxxx及setxxx方法,其中getxxx方 法没有方法参数,有返回值; setxxx方法没有返回值,有一个方法参数;那么内省机制就认为 xxx为一个属性;
例如下面代码
employee类中根本没有声明age属性,仅仅是声明了这样的getter和setter.内省机制就认为age是属性
package com.shixun.introspector;public class employee { private string name; private double score; // age将被内省认为是属性 public int getage(){ return 30; } // name将被内省认为是属性 public string getname() { return name; } public void setname(string name) { this.name = name; } // score将被内省认为是属性 public double getscore() { return score; } public void setscore(double score) { this.score = score; } public static void main(string[] args) { }}
相关api与java内省有关的主要类及接口有:
java.beans.introspector类: 为获得javabean属性、事件、方法提供了标准方法;通常使用其中的getbeaninfo方法返回beaninfo对象;
java.beans.beaninfo接口:不能直接实例化,通常通过introspector类返回该类型对象,提供了返回属性描述符对象(propertydescriptor)、方法描述符对象(methoddescriptor) 、 bean描述符(beandescriptor)对象的方法;
java.beans.propertydescriptor类:用来描述一个属性,该属性有getter及setter方法;
可以使用propertydescriptor类的方法获取属性相关的信息,例如getname方法返回属性的名字:
propertydescriptor类中定义了方法可以获取该属性的getter和setter方法
方法方法描述
method getreadmethod() 回属性对应的getter方法对象;
method getwritemethod() 回属性对应的setter方法对象;
下面我们来用代码深入探究一下:
代码案例:获取属性相关信息employee如上面代码所示,继续编写主函数进行测试
首先用beaninfo接口获取beaninfo的对象,再通过beaninfo对象获取propertydescriptor属性描述
//获取beaninfo的对象 beaninfo employeebeaninfo = introspector.getbeaninfo(employee.class); //通过beaninfo对象获取propertydescriptor属性描述 propertydescriptor[] propertydescriptors = employeebeaninfo.getpropertydescriptors(); system.out.println("通过inspector内省机制获取javabean属性======= 打印所有信息 ===================="); arrays.stream(propertydescriptors).foreach(f->{ system.out.println("===================================="); system.out.println("属性名:"+f.getname()); system.out.println("类型:"+f.getpropertytype()); system.out.println("get方法:"+f.getreadmethod()); system.out.println("set方法:"+f.getwritemethod()); });// 或者用增强forsystem.out.println("通过inspector内省机制获取javabean属性======= 打印所有信息 ====================");for (propertydescriptor propertydescriptor : propertydescriptors) { system.out.println("===================================="); system.out.println("名字:" + propertydescriptor.getname()); system.out.println("类型:" + propertydescriptor.getpropertytype()); system.out.println("get方法:" + propertydescriptor.getreadmethod()); system.out.println("set方法:" + propertydescriptor.getwritemethod());}
运行结果如下:
我们也可以通过反射调用这里获取的get或set方法
//创建employee的对象class<?> clazz = class.forname("com.shixun.introspector.employee");object employee = clazz.newinstance();//遍历属性描述对象for (propertydescriptor propertydescriptor : propertydescriptors) { //打印属性名称 system.out.println(propertydescriptor.getname()); //判断属性名称是不是name if (propertydescriptor.getname().equals("name")) { //setter方法 method writemethod = propertydescriptor.getwritemethod(); //调用setname方法 writemethod.invoke(employee, "jack"); //getter方法 method readmethod = propertydescriptor.getreadmethod(); //调用getname方法 object namevalue = readmethod.invoke(employee); system.out.println("name属性的值为:" + namevalue); } //判断属性名称是否为score if (propertydescriptor.getname().equals("score")) { //setter方法 method scorewritemethod = propertydescriptor.getwritemethod(); //调用setscore方法 scorewritemethod.invoke(employee, new double(3000)); //getter方法 method scorereadmethod = propertydescriptor.getreadmethod(); object scorevalue = scorereadmethod.invoke(employee); system.out.println("score属性的值为:" + scorevalue); }}system.out.println("当前对象的信息:"+employee.tostring());
运行结果如下所示:
全部代码附在最下方!!!!!!
内省属性的注意事项很多框架都使用了内省机制检索对象的属性,定义属性名字时,名字最好起码以两个小写字母开头,例如stuname,而不要使用sname,某些情况下,可能会导致检索属性失败;
内省机制检索属性时,是根据getter和setter方法确认属性名字,而不是根据类里声明的成员变量名称决定;
完整代码package com.shixun.introspector;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 java.util.arrays;public class employee { private string name; private double score; // age将被内省认为是属性 public int getage() { return 30; } // name将被内省认为是属性 public string getname() { return name; } public void setname(string name) { this.name = name; } // score将被内省认为是属性 public double getscore() { return score; } public void setscore(double score) { this.score = score; } @override public string tostring() { return "employee{" + "name='" + name + '\'' + ", score=" + score + '}'; } public static void main(string[] args) throws classnotfoundexception, introspectionexception, illegalaccessexception, instantiationexception, invocationtargetexception { //获取beaninfo的对象 beaninfo employeebeaninfo = introspector.getbeaninfo(employee.class); //通过beaninfo对象获取propertydescriptor属性描述 propertydescriptor[] propertydescriptors = employeebeaninfo.getpropertydescriptors();// system.out.println("通过inspector内省机制获取javabean属性======= 打印所有信息 ====================");// arrays.stream(propertydescriptors).foreach(f->{// system.out.println("====================================");// system.out.println("属性名:"+f.getname());// system.out.println("类型:"+f.getpropertytype());// system.out.println("get方法:"+f.getreadmethod());// system.out.println("set方法:"+f.getwritemethod());// });//////// system.out.println("通过inspector内省机制获取javabean属性======= 打印所有信息 ====================");//// for (propertydescriptor propertydescriptor : propertydescriptors) {// system.out.println("名字:" + propertydescriptor.getname());// system.out.println("类型:" + propertydescriptor.getpropertytype());// system.out.println("get方法:" + propertydescriptor.getreadmethod());// system.out.println("set方法:" + propertydescriptor.getwritemethod());// } //创建employee的对象 class<?> clazz = class.forname("com.shixun.introspector.employee"); object employee = clazz.newinstance(); //遍历属性描述对象 for (propertydescriptor propertydescriptor : propertydescriptors) { //打印属性名称 system.out.println(propertydescriptor.getname()); //判断属性名称是不是name if (propertydescriptor.getname().equals("name")) { //setter方法 method writemethod = propertydescriptor.getwritemethod(); //调用setname方法 writemethod.invoke(employee, "jack"); //getter方法 method readmethod = propertydescriptor.getreadmethod(); //调用getname方法 object namevalue = readmethod.invoke(employee); system.out.println("name属性的值为:" + namevalue); } //判断属性名称是否为score if (propertydescriptor.getname().equals("score")) { //setter方法 method scorewritemethod = propertydescriptor.getwritemethod(); //调用setscore方法 scorewritemethod.invoke(employee, new double(3000)); //getter方法 method scorereadmethod = propertydescriptor.getreadmethod(); object scorevalue = scorereadmethod.invoke(employee); system.out.println("score属性的值为:" + scorevalue); } } system.out.println("当前对象的信息:"+employee.tostring()); }}
以上就是java内省机制怎么实现的详细内容。
