Java基础--反射、内省
来源:互联网 发布:怎么当淘宝店铺客服 编辑:程序博客网 时间:2024/05/22 01:54
反射就是把Java类中的各种成分映射成相应的Java类
例如,一个Java类中用一个Class类的对象来表示,
一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。
表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,
这些信息就是用相应类的实例对象来表示,它们是Field(成员变量)、Method(方法)、Contructor(构造方法)、Package等等。
个人对反射的理解
pt1.getClass()获取到的是一个Class对象,这个对象不同于new出来的对象,有点类似于继承的子父类的关系,
pt1.getClass()获取到的对象相当于父类对象,是一个由class类直接获取到的Class对象,而不同于new出来的对象
pt1.getClass().getField("y")是通过这个Class对象获取到这个class类里面成员变量的一个操作权限,但只是获取了一个权限,没什么实际的用处
必须通过get获取set方法获取到操作某个对象的操作权限
用生活中的例子理解:
就像修手机的人,一个修手机的人他只会修手机的屏幕,就是说明这个人拥有修手机屏幕的权限,就相当于pt1.getClass().getField("y");所获取到的对y的控制权限
但是有些手机在还有没有生产出来之间,这个人就已经会修理屏幕了,很符合反射的原理,在对象还没有new出来之前他就已经拥有了控制y的权限
但是你会修手机屏幕,但没有手机也是不行的,没有东西修,一定要有一个手机给你修才行,手机就相当于new出来的对象
如何得到各个字节码对应的实例对象( Class类型)
类名.class,例如,System.class
对象.getClass(),例如,new Date().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date");
九个预定义Class实例对象:八个基本数据类型加一个void
参看Class.isPrimitive方法的帮助
Int.class == Integer.TYPE
//反射 import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflecDemo { public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub String str1 = "abc"; Class cls1 = str1.getClass(); Class cls2 = String.class; Class cls3 = Class.forName("java.lang.String"); System.out.println(cls1 == cls2); System.out.println(cls1 == cls3); System.out.println(cls1); /* boolean isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。 * */ System.out.println(cls1.isPrimitive());//判断是否是基本数据类型对象 System.out.println(int.class.isPrimitive()); System.out.println(int.class == Integer.class);//false System.out.println(int.class == Integer.TYPE);//true,将Integer.TYPE后就是基数据类型了 System.out.println(int[].class.isPrimitive());//false数组不是基本数据类型 System.out.println(int[].class.isArray());//true,判断数组要用isArray int[] a1 = new int[]{1,5,8}; int[] a2 = new int[4]; int[][] a3 = new int[3][4]; String[] a4 = new String[]{"a","c","b","d"}; System.out.println(a1.getClass() == a2.getClass()); //System.out.println(a1.getClass() == a4.getClass()); //System.out.println(a1.getClass() == a3.getClass()); System.out.println(a1.getClass().getName()); System.out.println(a1.getClass().getSuperclass().getName()); System.out.println(a4.getClass().getSuperclass().getName()); Object aObj1 = a1; Object aObj2 = a4; Object[] aObj4 = a3; Object[] aObj5 = a4; ArrayDemo(a4); ArrayDemo("zxc"); } //反射中数组的演示 public static void ArrayDemo(Object obj){ Class clazz = obj.getClass(); if (clazz.isArray()) { int len = Array.getLength(obj);//获取对象中数组的长度 for (int i=0 ;i<len;i++){ System.out.println(Array.get(obj,i)); } }else{ System.out.println(obj); } } //反射中Method(方法)的演示 public static void MethodDemo() throws Exception{ //getMethod(String name, Class<?>... parameterTypes) //返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 //name 参数是一个 String,用于指定所需方法的简称 //parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。如果 parameterTypes 为 null,则按空数组处理。 //invoke(Object obj, Object... args) //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 String str1 = "abc"; Method methodCharSt = String.class.getMethod("charAt", int.class);//int.class为所获取方法所接收的数据类型,可用于分别重载方法 System.out.println(methodCharSt.invoke(str1, 1));//使用反射使用charAt方法返回1位置上的值 //invoke(null, 1) 如果第一个参数为null,则调用的是静态方法 } //反射中Field(成员变量)的演示和说明 public static void FieldDemo() throws Exception{ ReflectPoint pt1 = new ReflectPoint(3,5); //getField,返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 Field fieldY = pt1.getClass().getField("y");//getField的参数为字段名 System.out.println(fieldY.get(pt1));//得到fieldY在pt1这个对象上的值 /*个人对反射的理解 pt1.getClass()获取到的是一个Class对象,这个对象不同于new出来的对象,有点类似于继承的子父类的关系, pt1.getClass()获取到的对象相当于父类对象,是一个由class类直接获取到的Class对象,而不同于new出来的对象 pt1.getClass().getField("y")是通过这个Class对象获取到这个class类里面成员变量的一个操作权限,但只是获取了一个权限,没什么实际的用处 必须通过get获取set方法获取到操作某个对象的操作权限 * */ //getDeclaredField,返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Field fieldX = pt1.getClass().getDeclaredField("x");//获取已被私有的成员变量用getDeclaredField //setAccessible,将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。 //值为 false 则指示反射的对象应该实施 Java 语言访问检查。 fieldX.setAccessible(true);//暴力反射 System.out.println(fieldX.get(pt1)); //演示使用反射替换字符串 changeStringValue(pt1); System.out.println(pt1); } public static void changeStringValue(Object obj) throws Exception{ Field[] fields = obj.getClass().getFields();//获取Field操作权限 for (Field field : fields){ if (field.getType() == String.class){ String oldValue = (String)field.get(obj);//对obj对象的Field进行操作,获取值 String newValue = oldValue.replace('b','a'); field.set(obj, newValue); } } } //反射中构造方法的演示 public static void ConstructorDemo() throws Exception{ /* * Constructor类代表某个类中的一个构造方法 得到某个类所有的构造方法: 例子:Constructor [] constructors= Class.forName("java.lang.String").getConstructors(); 得到某一个构造方法: 例子:Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class); //获得方法时要用到类型 创建实例对象: 通常方式:String str = new String(new StringBuffer("abc")); 反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc")); //调用获得的方法时要用到上面相同类型的实例对象 * */ //new String(new StringBuffer("abc")); Constructor constructor1 = String.class.getConstructor(StringBuffer.class);//获取构造方法(根据参数来确定获取那个构造方法) //使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 String str2 = (String)constructor1.newInstance(new StringBuffer("abc")); System.out.println(str2.charAt(2)); } }
内省
简单的说内省就是在javaBean中通过反射的机制来使用get,set方法
import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.*; import java.util.*; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; public class IntroSpectorDemo { /** * @param args */ public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub ReflectPoint pt1 = new ReflectPoint(3, 5); String propertyName = "x"; //获取值 Object retVal = getProperty(pt1, propertyName); System.out.println(retVal); //使用架包 System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName()); //设置值 Object value = 7; setPropertes(pt1, propertyName, value); //自动抽取方法,右键-->refactor-->Excract Method BeanUtils.setProperty(pt1, "x", 9); System.out.println(pt1.getX()); /* //java7新特性 Map map = (name:"zxx",age:18); BeanUtils.setProperty(map,"name", "lhm"); */ BeanUtils.setProperty(pt1, "birthday.time", "111"); System.out.println(BeanUtils.getProperty(pt1, "birthday.time")); PropertyUtils.setProperty(pt1, "x", 9); System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName()); } //PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。 //使用PropertyDescriptor不同于反射或者getX的区别在于,getX只能访问public权限的, //而PropertyDescriptor则可以访问所有权限,包括private private static void setPropertes(Object pt1, String propertyName, Object value) throws IntrospectionException, IllegalAccessException, InvocationTargetException { PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass()); //getWriteMethod 获得应该用于写入属性值的方法。 Method methodeSetX = pd2.getWriteMethod(); methodeSetX.invoke(pt1,value); } private static Object getProperty(Object pt1, String propertyName) throws IntrospectionException, IllegalAccessException, InvocationTargetException { PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); //getReadMethod() 获得应该用于读取属性值的方法。 Method methodeGetX = pd.getReadMethod(); Object retVal = methodeGetX.invoke(pt1); return retVal; } }
- Java基础--反射、内省
- java基础加强二 反射 内省
- JAVA基础之内省与反射
- java 反射和内省
- java内省与反射
- Java反射与内省
- java反射--内省实例
- java反射和内省
- java反射 内省
- Java新技术】反射,内省
- java反射与内省
- java反射和内省
- java反射和内省
- Java 反射与内省
- java反射、内省、注解
- Java反射与内省
- Java中的反射,内省
- java反射和内省
- bashrc_docker的脚本
- Android官方MVP架构示例项目解析
- zzuli 1872: Which Offer?【水】
- js中json 的增删改操作
- 技术总结
- Java基础--反射、内省
- mysql-proxy安装
- 模仿支付宝GridView 分割线实现
- 透明GIF图片显示控件
- 内部类的使用以及抽象类的实现
- Java 将18位身份证号转化为15位返回,非18位身份证号原值返回 单例
- ChemDraw到底是个什么
- Chromium 源码
- HDU 1258 Sum It Up (还是DFS)