zoukankan      html  css  js  c++  java
  • Spring基础之 反射(Reflection)

    1.了解Class

    package com.inspire.reflection.Class_api;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class ClassUtils {
        public static void main(String[] args) {
            String s="abc";
            printclassFieldMessage(s);
            printClassMethodMessage(s);
        }
        /**
         * 打印类的信息,成员方法
         * @param obj  该对象所属类的信息
         */
        public static void printClassMethodMessage(Object obj){
            //获取类的信息,获取类的类类型
            Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
            //获取类的名称
            System.out.println("类名是:"+c1.getName());
            //获取方法
            /*
            Method类,方法的对象
            一个成员方法就是一个Method对象
            getMethods方法获取的是所有的public的方法,包括父类继承而来的
            getDeclaredMethods方法获取的是所有该类自己定义的方法。不问访问权限
             */
            Method[] methods=c1.getMethods();
    //        Method[] method=c1.getDeclaredMethods();
            for (int i = 0; i <methods.length ; i++) {
                //获取方法的返回值类型的类类型(比如返回String类型,返回的是String.class)
                Class returnType=methods[i].getReturnType();
                System.out.print(returnType.getName()+" ");
    
                //获取方法的名称
                System.out.print(methods[i].getName()+"(");
    
                //获取参数类型   获取的是参数列表类型的类类型
                Class[] paramType=methods[i].getParameterTypes();
    
                for (Class c:paramType) {
                    System.out.print(c.getName()+",");
                }
                System.out.println(")");
            }
        }
        /**
         * 打印类的信息,成员变量
         * @param obj
         */
        public static void printclassFieldMessage(Object obj) {
            //获取成员变量
            /**
             * 成员变量也是对象
             * java.lang.reflect.Field
             * Field封装了关于成员变量的操作
             * getFields方法获取的是所有的public的成员变量信息
             * getDeclaredFields()获取的是该类自己声明的成员信息(public/private)
             */
            Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
            //Field[] fields=c1.getFields();
            Field[] fields=c1.getDeclaredFields();
            for (Field f:fields) {
                //得到成员变量类型的类类型
                Class fieldType=f.getType();
                //得到成员变量的名称
                String typeName=f.getName();
                System.out.println(typeName+" "+fieldType);
            }
        }
        /**
         * 打印对象的构造函数的信息
         * @param obj
         */
        public static void printClassConMessage(Object obj){
            Class c=obj.getClass();
            /*
            构造函数也是对象
            java.lang.Constructor中封装了构造函数的信息
            getDeclaredConstructor获取自己声明的构造函数
             */
            Constructor[] constructors=c.getDeclaredConstructors();
            //Constructor[] constructors=c.getConstructors();
            for (Constructor constructor:constructors) {
                System.out.println(constructor.getName()+"(");
                //获取构造函数的参数列表
                Class[] paramType=constructor.getParameterTypes();
                for (Class c1:paramType) {
                    System.out.print(c1.getName()+",");
                }
                System.out.println(")");
            }
        }
    }

    2.获取一个类的类对象

    (1).定义一个类

    public class Student {
        private int id;
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        private int age;
    
    }

    (2).获取类对象

    public class ClassDemo1 {
        public static void main(String[] args) {
            //Student的实例对象如何表示?
           // Student student=new Student();
            /*Student也是实例对象,是Class类的实例对象。如何表示?
            任何一个类都是Class类的实例对象,都有三种表示方法
            */
            //方式一:任何一个类都有一个隐含的静态成员class
            Class c1=Student.class;
            //方式二:已知该类的对象,通过getClass方法
            Student student=new Student();
            Class c2=student.getClass();
            /*
             c1,c2表示了Student类的类类型(Class type)
             万事万物皆对象
             类也是对象,是Class类的实例对象
             这个对象我们称为该类的类类型
              */
            //c1,c2都代表了Student类的类类型,一个类只可能是Class类的一个实例对象
            System.out.println(c1==c2);  //true
            //方式三:
            try {
                Class c3=Class.forName("com.inspire.reflection.Class_object.Student");
                System.out.println(c2==c3);  //true
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            /*
            有了类的类类型,我们可以通过类类型创建该类的对象.即通过c1,c2,c3创建对象
             */
            try {
                Student student1= (Student) c1.newInstance();
                //调用方法
                student1.getAge();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    3.通过反射调用方法

    public class Printer {
    
        public void printA(){
            System.out.println("无参的方法..........");
        }
        public void printA(int a,int b){
            System.out.println(a+":"+b);
        }
    
    }
    public class MethodDemo {
        public static void main(String[] args) {
            Printer printer=new Printer();
            Class c=printer.getClass();
            try {
                //获取方法
                Method method= c.getDeclaredMethod("printA", int.class, int.class);//获取自己声明的方法
                //c.getMethod("printA", int.class, int.class);//获取public的方法
                //方法的反射操作
                method.invoke(printer,1,3); //放回方法的返回值
                System.out.println("=========================");
                Method method1=c.getDeclaredMethod("printA");
                method1.invoke(printer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    4.通过反射理解泛型

    java中泛型是防止错误输入的。只在编译时有效。编译之后集合的泛型是去泛型化的
    public static void main(String[] args){
            ArrayList<String> list1=new ArrayList<String>();
            list1.add("hello");
         ArrayList list2=new ArrayList<String>();
         //System.out.println(c1==c2);//结果为true,说明编译之后集合的泛型是去泛型化的
            Class c2=list1.getClass();
            try {
                Method method=c2.getMethod("add", Object.class);
            //注意这里:虽然上面定义list1时是String类型的,但是这里可以加入int类型的数据
                method.invoke(list1,100);
                System.out.println(list1.size());
                System.out.println(list1);//不能用foreach遍历,类型不一样了
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
  • 相关阅读:
    oracle 对应的JDBC驱动 版本
    Java Web中如何访问WEB-INF下的XML文件
    网站制作越简单越好(一):css样式命名规范
    HTTPClient以WebAPI方式发送formData数据上传文件
    NetCore(依赖注入)
    JS a标签 onClick问题
    NetCore的配置管理(1)
    Centos 系统安装NetCore SDK命令以及一系列操作(3)
    Centos 系统安装NetCore SDK命令以及一系列操作(2)
    Centos 系统安装NetCore SDK命令以及一系列操作(1)
  • 原文地址:https://www.cnblogs.com/inspred/p/8908609.html
Copyright © 2011-2022 走看看