zoukankan      html  css  js  c++  java
  • JAVA 中的 反射

                        CLASS类

    1) 在面向对象的世界里,万事万物皆对象.
     在java中有两样东西不是面向对象 1.普通的数据类型(java中有封装类来弥补它) 2. java中静态的东西


    2) 类是对象吗? 类是对象,类是java.lang.Class类的实例对象


    3) 任何一个类都是CLass类的实例对象,有三种表示方法

     第一种表示方法  Class c1 = (类名).class;
     实际在告诉我们任何一个类都有一个隐含的静态成员变量class

     第二种表示方法 已经知道该类的对象通过getClass方法
     第三种官网 c1表示是类的类型(Classtype)万事万物皆对象 类也是对象 是Class类的实例队象这个对象我们称为该类的类类型
      Class c3 = null;
      c3 = Class.forName("reflexdemo.Foot") Class.forname中是类的全路径(含包名);

    我们可以通过类的类类型创建该类 的对象实例  通过c1 或者c3创建
     Foot foot=(Foot)c1.newInstance(); 需要强制类型转换

     1 package reflexdemo;
     2 
     3 /**
     4  * @2018年4月6日
     5  * @王 鸿
     6  * @Administrator
     7  */
     8 public class Foot {
     9     public int age = 10;
    10 }
    11 
    12 测试类
    13 
    14 package reflexdemo;
    15 
    16 /**
    17  * @2018年4月6日
    18  * @王 鸿
    19  * @Administrator
    20  */
    21 public class Refle_Demo_01 {
    22     public static void main(String[] args) throws Exception {
    23         // 创建一个Foot的实例对象
    24         Foot foot = new Foot();
    25         // 第一种 Foot这个类也是一个实例对象,Class类的对象
    26         Class c1 = Foot.class;
    27         // 第二种通过对象.getclass方法
    28         Class c2 = foot.getClass();
    29         // 不管 c1 ,c2 都代表着Foot类的类型,一个类只可能是class类的一个实例对象
    30         System.out.println(c1 == c2);
    31         // 第三种表达方式
    32         Class c3 = null;
    33         // Class.forname中是类的全路径(含包名)
    34         c3 = Class.forName("reflexdemo.Foot");
    35         System.out.println(c2 == c3);
    36         // 创建类的实例
    37         Foot foot1 = (Foot) c3.newInstance();// 需要无参的构造
    38         System.out.println(foot1.age);
    39     }
    40 }

    为什么需要反射?

    1 通过new创建对象 是静态加载类,在编译时刻就需要加载所有的可能使用的类 (通过动态加载类可以解决该问题)
    2 动态加载类是在运行的时刻加载 ------------------(一般情况下功能性的类使用动态加载类)

    动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多 态的应用,有以降低类之间的藕合性("套用别的博客一句话")

    下面的代码可以看到通过类 来反射类的信息 包括构造 还有方法

    package datatype;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * @2018年4月7日
     * @王 鸿
     * @Administrator
     */
    public class ClassMessage {
        /*
         * 打印类的信息 包括类的成员函数成员变量
         */
        public static void print(Object obj) {
            // 要获取类的信息 首先获取类的类类型
            Class c = obj.getClass(); // 传递的是那个子类的对象 c 就是那个类的类类型
            // 获取类的名称
            System.out.println("类的名称:" + c.getClass());
            /*
             * 一个成员方法就是一个 Method对象 .getMethods()是获取所有的public的函数包括父类继承而来
             * 
             * getDeclaredMethods()获取的是所有该类自己声明方法
             */
    
            Method[] methods = c.getMethods();
            for (int i = 0; i < methods.length; i++) {
                // 的到方法的返回类型
                Class returnType = methods[i].getReturnType();
                System.out.print(returnType.getName());
                // 得到方法的名称
                System.out.print(methods[i].getName() + "(");
                // 获取参数的类型-->得到的是参数列表的类类型
                Class[] parameterTypes = methods[i].getParameterTypes();
                for (Class class1 : parameterTypes) {
                    System.out.print(class1.getName());
                }
                System.out.println(")");
                FiledMessage(c);
            }
    
        }
    
        /*
         * 获取成员变量的信息
         */
        public static void FiledMessage(Object obj) {
            Class c = obj.getClass();
            Field[] declaredFields = c.getDeclaredFields();
            for (Field field : declaredFields) {
                // 得到成员变量的类型的类类行
                Class filedtype = field.getType();
                String name = filedtype.getName();
                // 得到成员变量的名称
                String filename = field.getName();
                System.out.println(name + " " + filename);
            }
        }
    
        /*
         * 打印构造函数的信息 获得所有的构造方法
         */
        public static void Constructor(Object obj) {
            Class c = obj.getClass();
            Constructor[] constructors = c.getDeclaredConstructors();
            for (Constructor cs : constructors) {
                System.out.print(cs.getName() + "(");
                // 获取构造函数的参数列表
                Class[] parameterTypes = cs.getParameterTypes();
                for (Class class1 : parameterTypes) {
                    System.out.print(class1.getName() + ",");
                }
                System.out.println(")");
            }
        }
    }
    
        /*
        *打印方法
        * 打印的方法是又新开了一个类
        */
        package datatype;
    
    import java.lang.reflect.Method;
    
    /**
     * @2018年4月8日
     * @王 鸿
     * @Administrator
     */
    
    public class MethodMessage {
        public static void main(String[] args) throws Exception {
            A a = new A();
            // 要想获得一个方法的信息首先要获得类的类类型
            Class type = a.getClass();
            // 获取方法 方法必须要有名称和参数列表
            /*
             * getMethod 获取的是public的方法 getDeclaredMethod自己声明的方法
             */
            Method method = type.getDeclaredMethod("append", String.class,
                    String.class);
            // 如果是私有的需要用.setAccessible(true)
            method.setAccessible(true);
            // 方法没有返回值返回的null 有返回值放回指定的返回值
            method.invoke(a, "1", "2");
    
        }
    }
    
    class A {
        public void print(int a, int b) {
            System.out.println(a + b);
        }
    
        private void append(String one, String two) {
            System.out.println(one + two);
        }
    }
    
    
    测试类
    
    package datatype;
    
    /**
     * @2018年4月7日
     * @王 鸿
     * @Administrator
     */
    public class ClassMessageText {
    
        public static void main(String[] args) {
            Integer type = 2;
            String string = "s";
            // ClassMessage.print(type);
            // ClassMessage.FiledMessage(new Integer(1));
            ClassMessage.Constructor(string);
        }
    }

    此处指截取了一张构造反射出来的结果 

    注意: 方法的反射 如果你的方法是私有的 需要加上 方法对象.setAccessible(true)

                                      通过反射了解集合泛型的本质
    反射的操作都是编译之后的操作,集合的泛型是去泛型化的
     java 中的集合泛型 是防止 错误输入的,只在编译阶段有效 绕过编译就无效了

    package genericparadigm;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    /**
     * @2018年4月8日
     * @王 鸿
     * @Administrator
     */
    public class GenericList {
        public static void main(String[] args) throws Exception, SecurityException {
            // 非泛型集合
            ArrayList one = new ArrayList();
    
            // 泛型集合
            ArrayList<String> list = new ArrayList<String>();
    
            Class class1 = one.getClass();
            Class class2 = list.getClass();
            System.out.println(class1 == class2); // true
            Method method = class2.getMethod("add", Object.class);
            method.invoke(list, 1);
    
            System.out.println(list.size()); // 1
    
        }
    }
  • 相关阅读:
    mysql错误Error(1133): Can’t find any matching row in the use
    xtrbackup备份mysql
    配置Mysql审计
    Mysql:sql语句
    mysql基准测试与sysbench工具
    tomcat排错以及优化
    nginx反向代理
    Nginx
    服务器归分第一篇
    Android安装BusyBox(三星N7108)
  • 原文地址:https://www.cnblogs.com/wh1520577322/p/8745277.html
Copyright © 2011-2022 走看看