黑马程序员---Java反射机制

来源:互联网 发布:jquery数组增加元素 编辑:程序博客网 时间:2024/06/08 08:35

反射(Reflection)

java中无论某一个类生成多少个对象,这些对象都会对应于同一个Class对象()一个类,对应于一个Class 对象。

1.发射的4个基本功能:

                                   1.在运行时判断任意一个对象所属的类。

                                   2.在运行时构造任意一个类的对象。

                                   3.在运行时判断任意一个类所具有的成员变量。

                                   4.在运行时调用任意一个对象的方法。

2.实现反射的类主要有5个:

                                   1.Class 类                             代表一个类,存在于java.lang 包中

                                   2.Field 类                               代表类的成员变量(也称属性),java.lang.reflect

                                   3.Method 类                           代表类的方法

                                   4.Constructor 类                   代表类的构造方法

                                   5.Array 类                               提供了动态创建数组,以及访问数组元素的静态方法



     * Class 代表一类什么样的事物?
     * 任何类型都可以用一个Class来表示,任何类型在内存中都是一份字节码。
     *
     * 如何给Class 赋值?
     * Class cls1=Person.class; 代表Person 那个类的字节码。
     * Class cls2=Date.class; 代表Date 那个类的字节码。

     * 有两种返回方式,
     * 第一种是该份字节码被加载过,java虚拟机里直接返回即可,
     * 第二种是Java虚拟机还没有该字节码,则用类加载器去加载,把加载进来的字节码缓存在虚拟机里,以后要得到该字节码就不用在加载了
     *
     * 得到字节码的方式有三种,使用平率都很高
     * 1.类名.class  固定的写法,
     * 2.对象.getClass();
     * 3.Class.forName("类名");  反射主要使用Class.forName("java.lang.string"); 因为在写源程序的时候还不知道类的名字

public static void main(String[] args)throws Exception{String str1="abc";Class cls1=str1.getClass();Class cls2=String.class;Class cls3=null;try {cls3 = Class.forName("java.lang.String");//必须做异常处理} catch (ClassNotFoundException e) {System.out.println(e.toString());}System.out.println(cls1 == cls2);//使用的字节码都是同一份,System.out.println(cls1 == cls3);//只要是在源程序中出现的类型,都有各自的Class实例对象,如:int[],void...System.out.println(cls1.isPrimitive());//isPrimitive该方法是String类的方法,用于判断String是否是使用的基本数据的字节码,结果是flaseSystem.out.println(int.class.isPrimitive());//int 是基本数据字节码System.out.println(int.class == Integer.class);//Integer 是一个类,而不是基本数据类型System.out.println(int.class == Integer.TYPE);//Integer类专门定义了一个常量TYPE,System.out.println(int[].class.isPrimitive());//数组是一种类型System.out.println(int[].class.isArray());//判断一个Class是不是数组 /* * 什么叫反射? * 反射就是把Java类中的各种成份,映射成相应的java类 * 例如: * 一个Java类用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息用一个个java类来表示。 */ //公有有属性的访问 Student st=new Student("a",5);Field fd1=st.getClass().getField("age");System.out.println(fd1.get(st));//私有属性的访问,使用setAccessible 方法,该方法可以强行调用Field fd2=st.getClass().getDeclaredField("name");fd2.setAccessible(true);//暴力反射,System.out.println(fd2.get(st));//访问方法Method metchar=Student.class.getMethod("show",int.class,int.class);System.out.println(metchar.invoke(st,1,2));//invoke方法指定要调用哪个对象的方法,传入传输changeStringvalue(st);System.out.print(st);//获取某个 类中所有的方法列表Class classType1=Student.class;//使用每个类内置的class方法获取//Class classType=Class.forName("FanSheDemo.Student");//指定包名。类名Method[] met=classType1.getDeclaredMethods();for(Method m:met){System.out.println(m);}}//修改成员变量的值private static void changeStringvalue(Object o){Field[] fd=o.getClass().getFields();for(Field f:fd){if(f.getType()==String.class){try {String aldValue=(String)f.get(o);String newValue=aldValue.replace('a', '1');f.set(o,newValue);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}}

        @Testpublic void FanShe1() throws Exception{Class clazz=Class.forName("FanSheDemo.Student");Constructor c = clazz.getConstructor(String.class,int.class);//这里由于知道反射的类的类型,所以可以指定,在不知道的情况下,应该是Object 类型Student st = (Student)c.newInstance("aa",22);System.out.println(st.show(1, 2));//这里等于是创建了一个Student 的对象,可以通过st 调用被反射类的方法}@Testpublic void FanShe2() throws Exception{Class clazz = Class.forName("FanSheDemo.Student");Constructor c = clazz.getDeclaredConstructor(int.class);//访问私有的成员,中间都带有Declared 表示是访问私有的c.setAccessible(true);//该方法用于强行访问私有方法, 称为暴力反射  不管是什么访问权限都可以访问Student st=(Student) c.newInstance(13333);}


0 0