反射与内省_JavaBean与内省
程序员文章站
2024-01-20 16:02:04
...
JavaBean 是一种JAVA语言写成的可重用组件。
为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,long和class方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制发现和操作这些JavaBean 的属性。
为了让程序员们更好的操作Java对象的属性,SUN公司开发了一套API,被业界内称为:内省;内省的出现有利于了对类对象属性的操作,减少了代码的数量。
内省访问JavaBean有两种方法:
一、通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
二、通过PropertyDescriptor来操作Bean对象
内省和反射有什么区别
反射式在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性
UserTest
package JavaBean;
public class UserTest {
public static void main(String[] args) {
User user=UserFactory.newUser();
System.out.println(user);
}
}
UserFactory
package JavaBean;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class UserFactory {
static Properties p=new Properties();
static {
//加载配置文件
InputStream inStream=Thread.currentThread().getContextClassLoader().getResourceAsStream("JavaBean/user.properties");
try {
p.load(inStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static User newUser() {
//获取bean信息中的属性描述器流程步骤:
//通过反射获取类信息(properties(key))->>通过自省获取bean信息(类信息)->>通过bean信息->>=返回属性描述器
String user=p.getProperty("user");
User user2 = null;
try {
//获取类信息
Class beanclass=Class.forName(user);
//通过类信息获取对象实例
try {
user2=(User) beanclass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//通过反省传入类信息参数->>获取bean信息
BeanInfo beaninfo=Introspector.getBeanInfo(beanclass);
//获取属性描述器
PropertyDescriptor[] pds=beaninfo.getPropertyDescriptors();
//通过for each获取单个属性描述器
for (PropertyDescriptor pd:pds) {
String name=pd.getName();
if("name".equals(name)) {
//获取写方法
Method m=pd.getWriteMethod();
try {
m.invoke(user2, p.getProperty("name"));
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if("nums".equals(name)) {
//获取系写方法
Method m=pd.getWriteMethod();
try {
int nums=Integer.parseInt(p.getProperty("nums"));
m.invoke(user2, nums);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (ClassNotFoundException | IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
User
package JavaBean;
public class User {
private String name;
private int nums;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNums() {
return nums;
}
public void setNums(int nums) {
this.nums = nums;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, int nums) {
super();
this.name = name;
this.nums = nums;
}
@Override
public String toString() {
return "User [name=" + name + ", nums=" + nums + "]";
}
}
user.properties
user=JavaBean.User
name=longlong
nums=1000