• java 反射


    一:
    java.lang.Class
    类:Class是一个类,构造方法是private,由JVM创建(无法直接new CLass(),其对象是内存里的一份字节码)。
    放射: 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。
    例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。
    Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。
    例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。
    reflection可以动态的载入并取得 Java 组件(类) 的属性。(来自Sun)

     Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

    基本的 Java类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法。

    如何得到类的信息: Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。如下,三种方法可以得到类的信息:

    可以通过类名称(Date.class);可以通过对象得到(p1.getclass);也可以通过一个运行时的字符串(Class.forname("XXXXX"))得到。

         Person p1 = new Person();
            //下面的这三种方式都可以得到字节码
            Class c1 = Date.class;
            Class<? extends Person> c2 = p1.getClass();
            Class<?> c3 = null;
            //若存在则加载,否则新建,往往使用第三种,类的名字在写源程序时不需要知道,到运行时再传递过来
            try {
               c3 = Class.forName("java.lang.String");
    // forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常 }
    catch (ClassNotFoundException e) { e.printStackTrace(); }

     下面有一个例子:

     Class c = null;
            try {
                c = Class.forName("reflection.Person");
                Method m[] = c.getDeclaredMethods();
    
                for (int i = 0; i < m.length; i++) {
                    System.out.println(m[i].toString());
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

    输出:如下,输出类的各方法名,以及它们的限制符,和返回类型和参数

    public void reflection.Person.setName(java.lang.String)
    public void reflection.Person.setAge(int)
    public int reflection.Person.getAge()
    private java.lang.String reflection.Person.func(java.lang.String)

    例2: 如下利用Class的newInstance方法相当于调用类的默认的构造器。如果类没有无参的构造器,就会抛出异常。

      Person  p = new Person(5, "");
    
            Class<? extends Person> c = p.getClass();
    
            try {
                Person da = c.newInstance();   
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

     二:常用方法

    1 isPrimitive(判断是否是基本类型的字节码)
    2 java中构造方法没有先后顺序,通过类型和参数个数区分。

            java中构造方法没有先后顺序,通过类型和参数个数区分

            try {
                Constructor<Person> con1 = Person.class.getConstructor(int.class, String.class);
                Constructor<Person> con2 = Person.class.getConstructor();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }

       3 Filed类代表某一类中的一个成员变量。

    Field[] f = Person.class.getFields();           // 只能得到public的
    Field f1 = Person.class.getField("age");     // 只能得到public的
    Field[] f2 = Person.class.getDeclaredFields();   //  各种可见性的都可以得到,但是继承的得不到
    Field f3 = Person.class.getDeclaredField("age");   //各种可见性的都可以得到,但是继承的得不到
    Person p = new Person(5, "jack");
    Field f3 = Person.class.getDeclaredField("age");
    f3.setAccessible(true);   // 如果是私有的属性, 一定要临时改其属性
    String rs = (String) f3.get(p);

     4:  给定一个类的全名,调用main方法:

           Method m = Class.forName(str).getMethod("main",String[].class);
          
            m.invoke(null, new Object[]{new String[]{"111","222","333"}});
            m.invoke(null, (Object)new String[]{"111","222","333"});//这个可以说明,数组也是Object

    5: 模拟instanceof 操作

     Person p = new Person(5, "jack");
    Person.class.isInstance(p);
     
    三:Method类
        try {
                String str = "shfsfs";
                //包开头是com表示是sun内部用的,java打头的才是用户的
                Method mtCharAt = String.class.getMethod("charAt", int.class);
                Object ch = mtCharAt.invoke(str, 1);//若第一个参数是null,则肯定是静态方法
                System.out.println(ch);
    
                System.out.println(mtCharAt.invoke(str, new Object[] {2}));//1.4语法
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
     

      

     

  • 相关阅读:
    日志文件压缩
    Exchange2010 部署
    预读取页面 Prefetching pages
    利用Response的WriteFile方法输出一些文件
    事务记录工作中遇到的问题
    Orchard源码分析(7.1):Routing(路由)相关
    关于挑库规则的问题
    Oracle认证考试:EBS模块中文名称及英文缩写
    Oracle EBS 实施方法论扫盲:都有哪些实施方法论
    [二次开发] EBS R12 探索之路【EBS 经典SQL分享】
  • 原文地址:https://www.cnblogs.com/liufei1983/p/10847650.html
Copyright © 2020-2023  润新知