反射获取属性、构造、方法
获得类的字节码对象:Class对象.三种获得的方式.
* 类名.class;
* 类的实例.getClass();
* Class.forName();
获得构造器:Constructor
获得属性:Field
获得方法:Method
package com.boomoom.demo3.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * 反射的测试的案例: * @author admin * 反射的目的是为了操作某个类的属性或方法 * */ public class ReflectDemo1 { @Test /** * 获得代表这个类加载到内存的字节码文件的对象Class对象. */ public void demo1() throws ClassNotFoundException{ // 一种:通过类名.class Class clazz1 = Person.class; // 二种:通过类的实例对象.getClass()方法获得. Person person = new Person(); Class clazz2 = person.getClass(); // 三种:使用Class的forName的静态方法获得.(推荐使用这种) Class clazz3 = Class.forName("com.boomoom.demo3.reflect.Person"); } @Test /** * 通过反射操作其构造方法: * DBUtils: Person person = queryRunner.query(sql,new BeanHanlder(Person.class)); */ public void demo2() throws Exception{ // 反射第一步获得Class对象. Class clazz = Class.forName("com.boomoom.demo3.reflect.Person"); // 采用默认的无参数的构造方法创建: // Person person = (Person) clazz.newInstance(); // person.run(); // 采用有参数的构造方法来创建对象:Person p = new Person("张森",38); Constructor c = clazz.getConstructor(String.class,Integer.class); Person p = (Person) c.newInstance("张森",38); System.out.println(p.name); System.out.println(p.age); } @Test /** * 通过反射获得类中的属性: */ public void demo3() throws Exception{ // 反射第一步获得Class对象. Class clazz = Class.forName("com.boomoom.demo3.reflect.Person"); // 获得属性: // 以下两种仅仅获得共有的属性: // clazz.getField("name"); // 获得某个属性 // Field[] fields = clazz.getFields(); // 获得所有属性 // 获得私有的属性: p.name = Field field1 = clazz.getDeclaredField("name"); field1.setAccessible(true); Field field2 = clazz.getDeclaredField("age"); field2.setAccessible(true); Constructor c = clazz.getConstructor(String.class,Integer.class); Person p = (Person) c.newInstance("张森",42); String name = (String) field1.get(p); Integer age = (Integer)field2.get(p); System.out.println(name+" "+age); } @Test /** * 通过反射获得类中的方法:并且让方法执行. * */ public void demo4() throws Exception{ // 反射第一步获得Class对象. Class clazz = Class.forName("com.boomoom.demo3.reflect.Person"); // 获得类中的方法: Method method = clazz.getDeclaredMethod("run"); method.setAccessible(true); method.invoke(clazz.newInstance());// p.run(); // 获得带有参数的方法: Method method2 = clazz.getDeclaredMethod("sayHello", String.class); String s = (String) method2.invoke(clazz.newInstance(), "凤姐"); // String s = p.sayHello("凤姐"); System.out.println(s); } /** * Servlet的执行过程: * <servlet> <servlet-name>ServletDemo1</servlet-name> <servlet-class>com.boomoom.demo2.servlet.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo1</servlet-name> <url-pattern>/ServletDemo1</url-pattern> </servlet-mapping> Class clazz = Class.forName("com.boomoom.demo2.servlet.ServletDemo1"); // Servlet servlet = (Servlet)clazz.newInstance(); Method method = clazz.getMethod("service",HttpServletRequest.class,HttpServletResponse.class); method.invoke(clazz.newInstance(),request,response); <package > <action name="/hello" class="com.boomoom.action.HelloAction" /> </package> <class name="com.boomoom.domain.User"> </class> */ }
内省
public void demo1() throws Exception{ // 获得了Bean的信息 BeanInfo beanInfo = Introspector.getBeanInfo(User.class); // 获得Bean的属性描述了 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for(PropertyDescriptor pd:pds){ System.out.println(pd.getName()); /*pd.getReadMethod(); // 获得get方法 pd.getWriteMethod();// 获得set方法.*/ } }
commons-beanutils-1.8.3.jar 是Apache出的 其 Populate 方法用来给对象中的属性赋值(BeanUtils.populate(p,map);)。参数1: 要设置属性的对象;参数2: 将属性以Map集合的形式传入Key : 属性的名称,Value: 属性具体的值。
使用内省自己封装一个MyBeanUtils:
package com.boomoom; import java.lang.reflect.Field; import java.util.Map; import java.util.Set; public class MyBeanUtils { private MyBeanUtils() {} //public static void setProperty(Object bean,String name,Object value) public static void setProperty(Object bean,String name,Object value) throws ReflectiveOperationException { //根据JavaBean对象获取对应的字节码对象 Class clazz = bean.getClass(); //根据字节码对象获取对应的Field对象 Field f = clazz.getDeclaredField(name); //设置权限,让虚拟机不进行访问的检查 f.setAccessible(true); //赋值 f.set(bean, value); } //public static String getProperty(Object bean,String name) public static String getProperty(Object bean,String name) throws ReflectiveOperationException { Class clazz = bean.getClass(); Field f = clazz.getDeclaredField(name); f.setAccessible(true); Object obj = f.get(bean); return obj.toString(); } //public static void populate(Object bean,Map map) public static void populate(Object bean,Map map) throws ReflectiveOperationException { //通过JavaBean对象来获取对应的字节码对象 Class clazz = bean.getClass(); //获取Map中所有的key Set keys = map.keySet(); for (Object key : keys) { try { //根据key来获取对应的Field对象 Field f = clazz.getDeclaredField(key.toString()); //根据key来获取Map中对应的value Object value = map.get(key); f.setAccessible(true); f.set(bean, value); } catch(NoSuchFieldException e) { //e.printStackTrace(); } } } }