黑马程序员-------(基础加强)反射

来源:互联网 发布:手机fps测试软件 编辑:程序博客网 时间:2024/06/07 07:19

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1.反射的概述

反射就是将java类中的成分映射成相应的java类,我们获取该类中所有的内容,而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这便于操作这些成员。直白的说反射就想剥洋葱一样去解剖类

反射大大的增强了程序的扩展性

反射的基石:Class类  Java程序中的各个Java类属于同一类事物,描述这些类事物的Java类名就是Class


2.反射应用

获取Class对象的方法

类名.class  例如:System.class     明确获取某个类的Class对象

对象.getClass()  例如:new Date().getClass()    如果知道一个类的对象 但不知道类型  用于获取对象的类型

Class.forName("类名")根据类名来获取,用于类加载


package day01;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {Class clazz1 = "abc".getClass();Class clazz2 = Class.forName("java.lang.String");Class clazz3 = String.class;System.out.println("相等吗?");System.out.println(clazz1==clazz2);System.out.println(clazz1==clazz3);/* * 相等吗? *true *true*/}}

反射的用法

1.反射调用构造函数

创建对象有两种方式

1)调用空参数的构造方法  使用Class类中的newInstance()方法

例:Class clazz = String.class;    Object obj = clazz.newInstance;

2)调用带有参数的构造方法  先要获取指定参数列表的构造函数   然后再通过该构造函数的对象的方法newInstance(实际参数) 进行队形的初始化

/* * 反射访问构造方法 */public static void getConstructorDemo() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{//获取String类的  带有StringBuffer参数的构造方法Constructor<String> con = String.class.getConstructor(StringBuffer.class);//用获得构造方法 创建一个对象String newInstan= con.newInstance(new StringBuffer("abc")); //编译不会出错,运行时会出错//String newInstan= con.newInstance("abc");  //argument type mismatch 类型不匹配  它需要的是Stringbuffer而不是String//打印字符串角标为2的字符System.out.println(newInstan.charAt(2));}

2.反射调用成员变量

获取类的Class对象 然后调用

Field field = clazz.getField(fieldName); 或 clazz.getDecllaredField(fieldName)方法

如果是私有的  就用到 setAccessible(true)


package day01;public class ReflectPoint {//成员变量public int x ;private int y;private String str = "haohaolll";private String str2 = "aaaaaaaaa";//构造函数public ReflectPoint(int x, int y) {super();this.x = x;this.y = y;}public ReflectPoint(){}@Overridepublic String toString() {// TODO Auto-generated method stubreturn str+"..."+str2;}}
/* * 反射访问成员变量 */public static void getField() throws Exception{// 创建一个ReflectPoint 的一个对象ReflectPoint point = new ReflectPoint(3,6);//获取ReflectPoint类的Class对象Class clz =  point.getClass();//获取成员变量xField fieldX = clz.getField("x");System.out.println(fieldX.get(point));//获取私有成员变量yField fieldY = clz.getDeclaredField("y");//设置访问权限fieldY.setAccessible(true);// 暴力访问System.out.println(fieldY.get(point));/*Field[] fields = clz.getDeclaredFields();for (Field field : fields) {System.out.println(field);}*/}

反射字段的练习

/* * 运用反射 替换对象中字符串中的字符 */public static  void changeChar(Object obj) throws Exception{//获取所有的字段Field[] fields = obj.getClass().getDeclaredFields();//循环所有的字段for (Field field : fields) {if(field.getType()==String.class){if(!field.isAccessible()){//设置私有的权限field.setAccessible(true);//获得对象数据String str = (String)field.get(obj);//交换位置 str = str.replace("a", "c"); //将新数据重新存入对象当中 field.set(obj, str);}else{String str = (String)field.get(obj); str = str.replace('a', 'c');field.set(obj, str);}}}}

3.反射调用方法

/* * 反射调用方法 */public static void getMethod(Object obj) throws Exception{//获取指定的方法Method method = obj.getClass().getMethod("charAt", int.class);//如果obj为 null是 说明调用的是静态方法method.invoke(obj, 44);//想要运行指定的方法,方法对象最清楚的   为了让方法运行,调用方法对象的invoke方法即可//方法运行必须要有明确的属性对象和具体的实际参数}


反射构造方法  在接受数组参数时有些不同

String startingClassName = args[0];Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);//mainMethod.invoke(null, new String[]{"111","444","555"});//会出现脚标溢出//应当把  new String[] 数组封装一下   或者把他强转成 Object类型mainMethod.invoke(null, new Object[]{new String[]{"111","444","555"}});

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------






0 0