您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > linux/Unix相关 > JAVA反射
java中的反射总结刚开始学习java的时候真的很难理解反射到底是个什么东西一些书籍,哪怕是很经典的书籍都解释的让人感觉懵懵的,或许的确是我太笨况且,网上说在将来学习框架的时候需要经常应用到反射机制,这样一来总让人心里有些不安就方才偶然又把讲解反射的章节和视频看了一点,觉得能理解一些了现在决定一鼓作气,边看边写,顺便把一些主要的内容和操作都记载到这里我想,对于我这么一个笨笨的人来说,学习的最好方法也许就是不断重复遇到不懂的知识就停下来把以往的重新学一遍,虽然浪费了很多时间,但对我也有些效果我的理解是:所谓反射,就是根据一个已经实例化了的对象来还原类的完整信息至少对我而言,我认为它带给我的好处是,让我从下往上的又了解了一遍面向对象x_x在此又痛恨一边那些厚部头们,把我的脑细胞搞死一片Class类如果要完成反射,那么必须了解Class类实例1:通过对象取得包名和类名12345678910111213packageorg.siu;classTest{}publicclassDemo{publicstaticvoidmain(String[]args){Testt=newTest();System.out.println(t.getClass());System.out.println(t.getClass().getName());}}编译结果如下,注意包的编译方式即可此处的getClass()方法是默认继承自Object类的在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例因此,这样一来就会牵扯到向上转型和向下转型的概念由于向下转型的不安全因素,在这里泛型也会接踵而来(不过我想说的是,此处的泛型设计很刺眼!尼玛,整个java的语法设计同样刺眼,超恶心!!!)实例2:Class类的实例化由于Class类没有构造方法,所以实例化Class类的方式有点特殊,有三种方式:对象.getClass()类.ClassforName()123456789101112131415161718192021222324252627classTest{}publicclassDemo{publicstaticvoidmain(String[]args){//方式一:Testt=newTest();Class?extendsTestc1=t.getClass();System.out.println(c1);//方式二://为了避免特殊性,这里不用Test类,而用java库中的String类ClassStringc2=String.class;System.out.println(c2);//方式三://forName()方法会抛出异常Class?c3=null;try{c3=Class.forName(Test);}catch(ClassNotFoundExceptione){e.printStackTrace();}System.out.println(c3);}}其中,forName()方法需要重点掌握,因为它可以在类不确定的情况下实例化Class,更具灵活性Class类的应用Class类中有一个方法叫做newInstance(),它可以用来创建一个Class类对象的新实例怎么说呢?Class对象包含的内容就是反射好的那个类,我们要构造那个类的新实例(新对象)实例3:Class类的无参构造对象12345678910111213141516171819202122232425publicclassDemo{publicstaticvoidmain(String[]args){//实例化Class对象,forName()方法会抛异常Class?c=null;try{//这里需要完整的包名和类名c=Class.forName(java.lang.String);}catch(ClassNotFoundExceptione){e.printStackTrace();}//生成一个字符串的引用Strings=null;try{//将构造好的对象向下转型为String类//newInstance()方法会抛异常s=(String)c.newInstance();}catch(InstantiationExceptione){e.printStackTrace();}catch(IllegalAccessExceptione){e.printStackTrace();}System.out.println(字符串长度:+s.length());}}这样就通过无参数的形式构造了一个新的对象,如同正常模式中通过无参构造方法来构造新对象一样我们知道,类中除了有无参构造方法,还会存在有参数的构造方法那在反射中如何通过有参数的形式构造对象呢?接着看实例4:Class类的有参构造对象1234567891011121314151617181920importjava.lang.reflect.Constructor;publicclassDemo{//下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{c=Class.forName(java.lang.String);}catch(ClassNotFoundExceptione){e.printStackTrace();}char[]ch={'h','e','l','l','o'};Strings=null;//获得Class类对象的有参构造方法,括号里面参数的写法是:类型.classConstructor?con=c.getConstructor(char[].class);//用此构造方法构造一个新的字符串对象,参数为一个char数组s=(String)con.newInstance(ch);System.out.println(构造的字符串:+s);}}我们还是使用String类做例,因为String类用的比较多,便于理解这里需要注意的是,构造方法需要使用getConstructor()方法获得至于参数类型则是:原有类型.class还有一点,无论是有参还是无参,这里所使用的构造方法,原本的类里面必须对应存在那么,如何才能知道原有类里面的构造方法,普通方法,继承的父类等详细信息呢?接着看获取类的结构要通过反射获取类的结构我们这里要导入一个新的包java.lang.reflect实例5:取得类的构造方法123456789101112131415161718importjava.lang.reflect.Constructor;importjava.util.Arrays;publicclassDemo{//下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{c=Class.forName(java.lang.Boolean);}catch(ClassNotFoundExceptione){e.printStackTrace();}//这里的getConstructors()方法返回的是一个Constructor数组Constructor?[]cons=c.getConstructors();//打印的方式你可以自己写,为了方便我用Arrays.toString(),凑合着看System.out.println(Arrays.toString(cons));}}我选择了Boolean类来做例,因为Boolean类的构造方法就两个,方便看实例6:取得类所实现的接口123456importjava.util.Arrays;publicclassDemo{publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{7891011121314c=Class.forName(java.lang.Boolean);}catch(ClassNotFoundExceptione){e.printStackTrace();}Class?[]in=c.getInterfaces();System.out.println(Arrays.toString(in));}}没什么好说的,看结果实例7:取得父类12345678910111213publicclassDemo{publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{c=Class.forName(java.lang.Boolean);}catch(ClassNotFoundExceptione){e.printStackTrace();}//注意了,这里不会是数组,why?Class?su=c.getSuperclass();System.out.println(su);}}别忘了,java中是单继承,父类只有一个实例8:取得类的全部方法1importjava.lang.reflect.Method;234567891011121314151617publicclassDemo{publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{c=Class.forName(java.lang.Boolean);}catch(ClassNotFoundExceptione){e.printStackTrace();}Method[]m=c.getMethods();//好吧,这次我就大发慈悲的写个打印列表出来for(inti=0;im.length;i++){System.out.println(m[i]);}}}截取一部分,看看,意思下就行了……这几个例子都比较简单实例9:取得本类的全部属性123456789101112131415importjava.lang.reflect.Field;classPerson{privateStringname;privateintage;}publicclassDemo{publicstaticvoidmain(String[]args)throwsException{Class?c=null;try{c=Class.forName(Person);}catch(ClassNotFoundExceptione){e.printStackTrace();}161718192021Field[]f=c.getDeclaredFields();for(inti=0;if.length;i++){System.out.println(f[i]);}}}getDeclaredFielsd()方法可以获取全部属性,getFields()只能获取公共属性实例10:获取本类中属性的值1234567891011121314151617181920212223242526importjava.lang.reflect.Field;classPerson{publicStringname;privateintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}}publicclassDemo{publicstaticvoidmain(String[]args)throwsException{Personp=newPerson(zhangsan,12);Class?c=p.getClass();//获取公共属性的值Fieldf1=c.getField(
本文标题:JAVA反射
链接地址:https://www.777doc.com/doc-7028400 .html