收藏 分销(赏)

java中的反射总结.doc

上传人:仙人****88 文档编号:12004551 上传时间:2025-08-26 格式:DOC 页数:12 大小:298.73KB 下载积分:10 金币
下载 相关 举报
java中的反射总结.doc_第1页
第1页 / 共12页
java中的反射总结.doc_第2页
第2页 / 共12页


点击查看更多>>
资源描述
Class类 如果要完成反射,那么必须了解Class类 实例1:通过对象取得包名和类名 1 2 3 4 5 6 7 8 9 10 11 12 13 package org.siu;   class Test {       }   public class Demo {     public static void main(String[] args) {         Test t = new Test();         System.out.println(t.getClass());         System.out.println(t.getClass().getName());     } } 编译结果如下,注意包的编译方式即可 此处的getClass()方法是默认继承自Object类的   在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例 因此,这样一来就会牵扯到向上转型和向下转型的概念 由于向下转型的不安全因素,在这里泛型也会接踵而来 (不过我想说的是,此处的泛型设计很刺眼!尼玛,整个java的语法设计同样刺眼,超恶心!!!)   实例2:Class类的实例化 由于Class类没有构造方法,所以实例化Class类的方式有点特殊,有三种方式: 对象.getClass( ) 类.Class forName( ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Test {       }   public class Demo {     public static void main(String[] args) {         //方式一:         Test t = new Test();         Class<? extends Test> c1 = t.getClass();         System.out.println(c1);                   //方式二:         //为了避免特殊性,这里不用Test类,而用java库中的String类         Class<String> c2 = String.class;         System.out.println(c2);                   //方式三:         //forName()方法会抛出异常         Class<?> c3 = null;         try {             c3 = Class.forName("Test");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         System.out.println(c3);     } }  其中,forName( )方法需要重点掌握,因为它可以在类不确定的情况下实例化Class,更具灵活性   Class类的应用 Class类中有一个方法叫做newInstance( ),它可以用来创建一个Class类对象的新实例 怎么说呢?Class对象包含的内容就是反射好的那个类,我们要构造那个类的新实例(新对象) 实例3:Class类的无参构造对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Demo {     public static void main(String[] args) {         //实例化Class对象,forName()方法会抛异常         Class<?> c = null;         try {             //这里需要完整的包名和类名             c = Class.forName("java.lang.String");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }                   //生成一个字符串的引用         String s = null;         try {             //将构造好的对象向下转型为String类             //newInstance()方法会抛异常             s = (String) c.newInstance();         } catch (InstantiationException e) {             e.printStackTrace();         } catch (IllegalAccessException e) {             e.printStackTrace();         }         System.out.println("字符串长度: " + s.length());     } } 这样就通过无参数的形式构造了一个新的对象,如同正常模式中 通过无参构造方法来构造新对象一样 我们知道,类中除了有无参构造方法,还会存在有参数的构造方法 那在反射中如何通过有参数的形式构造对象呢?接着看   实例4:Class类的有参构造对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.lang.reflect.Constructor;   public class Demo {     //下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("java.lang.String");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         char[] ch = {'h','e','l','l','o'};         String s = null;         //获得Class类对象的有参构造方法,括号里面参数的写法是:类型.class         Constructor<?> con = c.getConstructor(char[].class);         //用此构造方法构造一个新的字符串对象,参数为一个char数组         s = (String) con.newInstance(ch);         System.out.println("构造的字符串:" + s);     } } 我们还是使用String类做例,因为String类用的比较多,便于理解 这里需要注意的是,构造方法需要使用getConstructor( )方法获得 至于参数类型则是:原有类型.class 还有一点,无论是有参还是无参,这里所使用的构造方法,原本的类里面必须对应存在 那么,如何才能知道原有类里面的构造方法,普通方法,继承的父类等详细信息呢?接着看   获取类的结构 要通过反射获取类的结构我们这里要导入一个新的包java.lang.reflect 实例5:取得类的构造方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.lang.reflect.Constructor; import java.util.Arrays;   public class Demo {     //下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("java.lang.Boolean");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         //这里的getConstructors()方法返回的是一个Constructor数组         Constructor<?>[] cons = c.getConstructors();         //打印的方式你可以自己写,为了方便我用Arrays.toString(),凑合着看         System.out.println(Arrays.toString(cons));     } }  我选择了Boolean类来做例,因为Boolean类的构造方法就两个,方便看   实例6:取得类所实现的接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import java.util.Arrays;   public class Demo {     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("java.lang.Boolean");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         Class<?>[] in = c.getInterfaces();         System.out.println(Arrays.toString(in));     } }  没什么好说的,看结果   实例7:取得父类 1 2 3 4 5 6 7 8 9 10 11 12 13 public class Demo {     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("java.lang.Boolean");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         //注意了,这里不会是数组,why?         Class<?> su = c.getSuperclass();         System.out.println(su);     } }  别忘了,java中是单继承,父类只有一个   实例8:取得类的全部方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import java.lang.reflect.Method;   public class Demo {     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("java.lang.Boolean");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         Method[] m = c.getMethods();         //好吧,这次我就大发慈悲的写个打印列表出来         for (int i = 0; i < m.length; i++) {             System.out.println(m[i]);         }     } }  截取一部分,看看,意思下就行了……这几个例子都比较简单   实例9:取得本类的全部属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.lang.reflect.Field;   class Person {     private String name;     private int age; }   public class Demo {     public static void main(String[] args) throws Exception {         Class<?> c = null;         try {             c = Class.forName("Person");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         Field[] f = c.getDeclaredFields();         for (int i = 0; i < f.length; i++) {             System.out.println(f[i]);         }     } } getDeclaredFielsd()方法可以获取全部属性,getFields()只能获取公共属性   实例10:获取本类中属性的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import java.lang.reflect.Field;   class Person {     public String name;     private int age;           public Person(String name, int age) {         this.name = name;         this.age = age;     } }   public class Demo {     public static void main(String[] args) throws Exception {         Person p = new Person("zhangsan",12);           Class<?> c = p.getClass();                   //获取公共属性的值         Field f1 = c.getField("name");         //get(p)表明要获取是哪个对象的值         String str = (String) f1.get(p);         System.out.println("姓名: " + str);                   //获取私有属性的值         Field f2 = c.getDeclaredField("age");         //age是私有属性,所以要设置安全检查为true         f2.setAccessible(true);         int age = (int) f2.get(p);         System.out.println("年龄: " + age);     } }  要注意的是:setAccessible()方法可以设置是否访问和修改私有属性   坦白说,java学到现在我还没发现什么能亮瞎我钛金眼的知识在里边 每次都是写一堆繁琐的语法实现个小玩意儿,不然就是拼命调用API,拼命的抛异常 让本身显得不够紧凑的代码变得愈发累赘 如果我喜欢一门语言,在我利用它做出东西来之前,它本身的特性必须能够打动我 显然,java并不让我快乐,也许很多程序员跟我一样是被迫使用java的 仅以此来安抚我那颗孤独编码的心,下面接着看内容   反射的应用 实例11:通过反射修改属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import java.lang.reflect.Field;   class Person {     private String name;           public Person(String name) {         this.name = name;     }           public String toString() {         return "姓名: " + this.name;     } }   public class Demo {     public static void main(String[] args) throws Exception {         Person p = new Person("王二狗");         System.out.println(p);         Class<?> c = p.getClass();               //定义要修改的属性         Field f = c.getDeclaredField("name");         f.setAccessible(true);         //修改属性,传入要设置的对象和值         f.set(p, "张二蛋");         System.out.println(p);     } }  几个方法都是有联系的,如果看不懂就先熟悉上面几个例子   实例12:通过反射调用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.lang.reflect.Method;   class Person {     public void print(int i) {         System.out.println("我在写数字: " + i);     }           public static void say(String str) {         System.out.println("我在说: " + str);     } }   public class Demo {     public static void main(String[] args) throws Exception {         Person p = new Person();         Class<?> c = p.getClass();               //getMethod()方法需要传入方法名,和参数类型         Method m1 = c.getMethod("print", int.class);         //invoke()表示调用的意思,需要传入对象和参数         m1.invoke(p, 10);                   Method m2 = c.getMethod("say", String.class);         //这里的null表示不由对象调用,也就是静态方法         m2.invoke(null, "你妹");     } } 这里演示了一个普通的有参方法和一个静态方法 既然有参数的都写出来了,那么无参的就更简单了,直接传入一个对象即可   实例13:通过反射操作数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.lang.reflect.Array;   public class Demo {     public static void main(String[] args) throws Exception {         int[] arr = {1,2,3,4,5};         Class<?> c = arr.getClass().getComponentType();                   System.out.println("数组类型: " + c.getName());         int len = Array.getLength(arr);         System.out.println("数组长度: " + len);         System.out.print("遍历数组: ");         for (int i = 0; i < len; i++) {             System.out.print(Array.get(arr, i) + " ");         }         System.out.println();         //修改数组         System.out.println("修改前的第一个元素: " + Array.get(arr, 0));         Array.set(arr, 0, 3);         System.out.println("修改后的第一个元素: " + Array.get(arr, 0));     } }  这里要注意一点,getComponentType( )返回的是数组元素的Class  
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服