黑马程序员——高新技术3——反射和JavaBean
来源:互联网 发布:知乎 大胸妹子 编辑:程序博客网 时间:2024/06/06 01:40
反射概述
反射就是把Java语言中的类,类成员,数组和枚举映射成相应的Java类,从而完成一些正常情况下完成不了的功能。
反射很耗性能,反射的作用相当于在运行时修改Java源代码。很多测试和反编译工具就是反射实现。
反射机制主要用到了下面的类和方法:
上面带下划线的表示静态成员
反射类及对象
package cn.itcase.day1;/** * 反射代码例子——Class类 * @author zwl */public class ReflectionDemo {public static void main(String[] args){//第一种获取Class类对象(字节码)的方法:类名.classClass cls1=Person.class;//第二种获取Class类对象(字节码)的方法:对象名.getClass()Person person=new Person();Class cls2=person.getClass();//第三种获取Class类对象(字节码)的方法:Class.forName("完整限定类名");Class cls3=null;try {//注意这里必须进行异常处理否则无法编译,forName()方法参数必须加包名,否则报异常cls3=Class.forName("cn.itcase.day1.Person");} catch (ClassNotFoundException e) {System.err.println("Person类未找到");}//测试是否获取的是内存上同一个字节码System.out.println(cls1==cls2);//trueSystem.out.println(cls2==cls3);//true}}class Person{}
public class ReflectionDemo {public static void main(String[] args){//基本数据类型的字节码Class cls1=int.class;Class cls2=Integer.class;//基本数据类型的字节码和它的封装类的字节码不同哦System.out.println(cls1==cls2);//false}}
反射构造函数
public static void main(String[] args)throws Exception{//获取String类的构造方法String(StringBuffer buffer)的Constructor对象Constructor constructor= String.class.getConstructor(StringBuffer.class);//用Constructor的对象创建一个String类的实例,参数是一个StringBuffer对象String str1=(String)constructor.newInstance(new StringBuffer("反射构造方法"));System.out.println(str1);}其中第2行的getConstructor方法的参数的作用是指定要获取String类的哪个构造方法,该参数是要获取的构造方法的参数类型的字节码。例如要获取构造方法public String(StringBuffer s)的Constructor对象,则getConstructor方法要传入参数StringBuffer.class,而如果要获取public String(byte[] bytes,int offset,int length)的Constructor对象,则getConstructor方法的参数要传入byte[].class,int.class,int.class三个参数。
反射字段
public class Point {public int x;private int y;public Point(int x, int y) {this.x = x;this.y = y;}}然后在主函数中反射成员变量:
public class ReflectionDemo {public static void main(String[] args)throws Exception{Point point=new Point(3, 5);//反射公有成员变量xField xField=Point.class.getField("x");System.out.println(xField.get(point));//反射私有成员变量yField yField=Point.class.getDeclaredField("y");yField.setAccessible(true);System.out.println(yField.get(point));}}其中getField方法用于获取公有成员变量,getDeclaredField方法用于私有成员变量,setAccessible用于获取对私有成员的访问权限,Field对象的get方法用于获取指定对象实例的指定成员变量的值。
反射字段练习
import java.lang.reflect.Field;public class ReflectionDemo {public static void main(String[] args)throws Exception{Person person=new Person();ChangeValue(person);System.out.println(person);}public static void ChangeValue(Object object) throws Exception{Field[] fields=Person.class.getFields();for (Field field : fields) {if (field.getType()==String.class) {String oldValue=(String)field.get(object);String newValue=oldValue.replace('b', 'a');field.set(object,newValue);}}}}Person类的代码如下:
public class Person {public String name1="ball";public String name2="basketball";public String name3="point";public String toString(){return name1+"\n"+name2+"\n"+name3;}}
反射方法
class MethodReflection{public void show(){System.out.println("调用了show()");}public String show(int a){System.out.println("调用了show(int a)");return "返回值:"+(a+1);}private int[] show(int[] inputs){System.out.println("调用了show(int[] inputs)");for (int i = 0; i < inputs.length; i++) {inputs[i]+=1;}return inputs;}public static void show(String[] args){for (String string : args) {System.out.println(string);}}}用反射调用MethodReflection类中的各个方法
import java.lang.reflect.Method;public class ReflectionDemo {public static void main(String[] args)throws Exception{RefectionMethod();}public static void RefectionMethod()throws Exception{//调用public void show()Method showMethod1=MethodReflection.class.getMethod("show");MethodReflection mr1=new MethodReflection();showMethod1.invoke(mr1);//调用public String show(int a),并打印方法的返回值Method showMethod2=MethodReflection.class.getMethod("show",int.class);MethodReflection mr2=new MethodReflection();Object primitiveReturnValue= showMethod2.invoke(mr2, 3);String needReturnValue=(String)primitiveReturnValue;System.out.println(needReturnValue);//调用private int[] show(int[] inputs)Method showMethod3=MethodReflection.class.getDeclaredMethod("show",int[].class);showMethod3.setAccessible(true);MethodReflection mr3=new MethodReflection();int[] arg3=new int[]{1,2,3,4};Object primitiveReturnValue3= showMethod3.invoke(mr3, arg3);int[] needReturnValue3=(int[])primitiveReturnValue3;for (int i : needReturnValue3) {System.out.println(i);}//public static void show(String[] args)Method showMethod4=MethodReflection.class.getMethod("show",String[].class);String[] strings=new String[]{"字符串1","字符串2","字符串3"};showMethod4.invoke(null, (Object)strings);//因为String[]类型会被当成多个参数,所以此处需要“打包”下}}
数组的反射
public static void arrayReflection(){int[] a=new int[]{1,2,3};for (int i = 0; i <Array.getLength(a); i++) {System.out.println(Array.get(a, i));}}
JavaBean
JavaBean就是符合如下规则的Java类:
1.必须有无参构造函数
2.必须有get方法(无参)和set方法(有参)
例子代码如下:
public class Person {private int x;public int getAge(){return x;}public void setAge(int age){this.x=age;}}
内省
内省英文为Introspector,主要用于操作javabean。
内省访问JavaBean有两种方式:
1.通过PropertyDescriptor类来操作JavaBean对象
2.通过Introspector类获取JavaBean对象的BeanInfo,然后通过BeanInfo来获取所有属性的PropertyDescriptor(属性描述器)数组,然后通过遍历这个数组来获取某个属性的名称、类型、getter和setter方法,进而可以通过反射来调用这些方法。
下面是内省所涉及的所有的类及方法的UML类图:
下面的例子用PropertyDescriptor类读写Javabean类对象的属性值(以上面的Person类为例):
import java.beans.PropertyDescriptor;import java.lang.reflect.Method;public class IntrospectionDemo {public static void main(String[] args)throws Exception {Person person=new Person();person.setAge(22);//内省get方法String propertyName="age";PropertyDescriptor pd=new PropertyDescriptor(propertyName, person.getClass());Method method=pd.getReadMethod();Object ret=method.invoke(person);System.out.println(ret);//内省set方法Object value=22;PropertyDescriptor pd2=new PropertyDescriptor(propertyName, person.getClass());Method method2=pd2.getWriteMethod();method2.invoke(person, value);//打印ageSystem.out.println(person.getAge());}}
上面的代码第9、10、11行可以用MyEclipse抽取成单独的方法,MyEclipse自动抽取方法功能的原则是,上面声明和初始化,此处调用的为输入参数;此处声明和赋值,下面调用的为返回值。也就是说选择抽取方法的代码块中,至多有一个变量被下面的代码调用,否则无法抽取。
将上一段代码中的两个内省操作(9、10、11行)(15、16、17行)抽取成单独的方法:
import java.beans.IntrospectionException;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class IntrospectionDemo {public static void main(String[] args)throws Exception {Person person=new Person();person.setAge(22);//内省get方法String propertyName="age";Object ret = getProperty(person, propertyName);System.out.println(ret);//内省set方法Object value=22;setProperty(person, propertyName, value);//打印ageSystem.out.println(person.getAge());}private static void setProperty(Person person, String propertyName,Object value) throws IntrospectionException,IllegalAccessException, InvocationTargetException {PropertyDescriptor pd2=new PropertyDescriptor(propertyName, person.getClass());Method method2=pd2.getWriteMethod();method2.invoke(person, value);}private static Object getProperty(Object obj, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException {PropertyDescriptor pd=new PropertyDescriptor(propertyName, obj.getClass());Method method=pd.getReadMethod();Object ret=method.invoke(obj);return ret;}}
复杂内省
下面的代码演示用Introspector类对象的方法来获取JavaBean的属性信息,和上一节的代码功能一致:
import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;public class IntrospectionDemo {public static void main(String[] args)throws Exception {Person person=new Person();person.setAge(22);String propertyName="age";Object ret = getProperty(person, propertyName);System.out.println(ret);Object value=26;setProperty(person, propertyName, value);//打印ageSystem.out.println(person.getAge());}//内省set方法private static void setProperty(Object obj, String propertyName,Object value) throws IntrospectionException,IllegalAccessException, InvocationTargetException {//PropertyDescriptor pd2=new PropertyDescriptor(propertyName, person.getClass());//Method method2=pd2.getWriteMethod();//method2.invoke(person, value);BeanInfo beanInfo=Introspector.getBeanInfo(obj.getClass());PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();for (PropertyDescriptor pDescriptor : pds) {if (pDescriptor.getName().equals(propertyName)) {pDescriptor.getWriteMethod().invoke(obj, value);}}}//内省get方法private static Object getProperty(Object obj, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException {//PropertyDescriptor pd=new PropertyDescriptor(propertyName, obj.getClass());//Method method=pd.getReadMethod();//Object ret=method.invoke(obj);BeanInfo beanInfo=Introspector.getBeanInfo(obj.getClass());Object ret=null;PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {if (propertyDescriptor.getName().equals(propertyName)) {ret=propertyDescriptor.getReadMethod().invoke(obj);}}return ret;}}
BeanUtils工具包
BeanUtils是Apache(一个软件基金会,中文名阿帕奇)提供的一个用于简化操作Javabean的代码的类库。
下载地址:点这里
导入方法:见这里
导入BeanUtils类库后还需导入阿帕奇的logging包。
使用方法见如下代码:
import org.apache.commons.beanutils.BeanUtils;public class IntrospectionDemo {public static void main(String[] args)throws Exception {Person person=new Person();person.setAge(22);String propertyName="age";//Object ret = getProperty(person, propertyName);Object ret=BeanUtils.getProperty(person, propertyName);System.out.println(ret);Object value=26;//setProperty(person, propertyName, value);BeanUtils.setProperty(person, propertyName, value);//打印ageSystem.out.println(person.getAge());}}
- 黑马程序员——高新技术3——反射和JavaBean
- 黑马程序员——高新技术(day2)反射,JavaBean的操作和注解的应用
- 黑马程序员——高新技术--JavaBean
- 黑马程序员—JAVA高新技术之JavaBean
- 黑马程序员——高新技术之 反射
- 黑马程序员——高新技术---反射
- 黑马程序员——高新技术(反射)
- 黑马程序员——【Java】【高新技术】反射
- 黑马程序员——高新技术---反射
- 黑马程序员java高新技术——反射
- 黑马程序员——高新技术之反射
- 黑马程序员——高新技术.反射
- 黑马程序员——java高新技术:反射
- 黑马程序员——高新技术(反射)
- 黑马程序员——Java高新技术---反射
- 黑马程序员——java高新技术--反射
- 黑马程序员——高新技术---反射
- 黑马程序员——Java高新技术---反射
- ZipHelper zip压缩工具包
- 第八周项目3 多分段函数求值
- 【一些题】一些重要函数的实现
- 从零开始学android<Bitmap图形组件.四十七.>
- POJ2478 Farey Sequence【快速求欧拉函数】
- 黑马程序员——高新技术3——反射和JavaBean
- leetcode minimum depth(binary tree)
- hdu 4888 最大流慢板
- leetcode Rotate Image
- DocumentHelper xml工具包
- 程序员练级攻略
- 网络解析1——TCP滑动窗口机制解释1
- 系统原理分析架构-三--代理服务器简介及分类
- HTTP与HTTPS