• Java反射总结


    这篇博客对于Java中的反射机制,做一些总结,有不完善的地方再继续补充。

    一. 定义
    JAVA反射机制(The JAVA reflection mechanism)是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    二. 功能
    在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    三. 使用
    1.首先我们想通过反射获取类或者接口的属性和方法,就必须获得这个类或者接口的Class对象。有以下三种方法:
    1).使用使用Class类的静态方法 Class.forName(String name)
    2).类的语法,Stirng.class
    3).使用类的实例化的getClass方法 obj.getClass();

    2.获取类的构造器

    1).public Constructor<?>[] getConstructors()      返回类中所有的public构造器集合,默认构造器的下标为0
    2).public Constructor<T> getConstructor(Class<?>... parameterTypes)   返回指定public构造器,参数为构造器参数类型集合
    3).public Constructor<?>[] getDeclaredConstructors()  返回类中所有的构造器,包括私有
    4).public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器

    3.获取类的成员变量

    1).public Field getDeclaredField(String name)  获取任意指定名字的成员变量
    2).public Field[] getDeclaredFields()             获取所有的成员变量
    3).public Field getField(String name)           获取任意public成员变量
    4).public Field[] getFields()                          获取所有的public成员变量
    Field 重要方法set(Object obj, Object value),将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

    4.获取类的方法

    1).public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
    2).public Method[] getDeclaredMethods()  获取所有的方法
    3).public Method[] getMethods()    获取所有的共有方法的集合
    4).public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法
    Method重要方法invoke(Object obj ,Object…parmasType),调用由此 Method 对象表示的底层方法。
    

    getMethods()和getDeclaredMethods()区别
    getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
    getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。

    示例代码:
    1. StudentBean类

    package com.li.reflection;
    
    public class StudentBean {
    
        public String id;
        public String name;
        public String sex;
        public String age;
        private String height;
    
        public StudentBean() {
            // TODO Auto-generated constructor stub
        }
    
        public StudentBean(String id) {
            super();
            this.id = id;
        }
    
        public StudentBean(String id, String name, String sex, String age) {
            super();
            this.id = id;
            this.name = name;
            this.sex = sex;
            this.age = age;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getHeight() {
            return height;
        }
    
        public void setHeight(String height) {
            this.height = height;
        }
    
    
        @Override
        public String toString() {
            return "StudentBean [id=" + id + ", name=" + name + ", sex=" + sex
                    + ", age=" + age + ", height=" + height + "]";
        }
    
        private void goToSchool(){
            System.out.println("Go to School");
        }
    
        public void eat(String food){
            System.out.println("eat "+food);
        }
    
        public boolean finishHomework(){
            System.out.println("finishHomework?");
            return true;
        }
    }
    
    
    2.使用
    package com.li.reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class ReflectionDemo {
    
        public static void main(String[] args) throws Exception{
    
            /**
             * 想要通过反射来获取类或者接口的属性和方法,首先获得这个类或者接口的Class对象
             */
            Class<?> cls;
    
            System.out.println("------------------Get Class------------------");
            //1.Class对象的静态方法    Class.forName(包名+类名)
            cls = Class.forName("com.li.reflection.StudentBean");
            //2.获得接口的静态方法   eg String.class
    //      cls = StudentBean.class;
            //3.通过类或者接口的实例化对象 getClass()方法
    //      StudentBean student = new StudentBean();
    //      cls = student.getClass();
            System.out.println(cls.toString()); 
    //输出: class com.li.reflection.StudentBean       
    
            System.out.println("------------------Get Constructor------------------");
            getConstructor(cls);
    
            System.out.println("------------------Get Field------------------");
            getField(cls);
    
            System.out.println("------------------Get Method------------------");
            getMethod(cls);
        }
    
        /**
         * 获得构造器创建对象
         */
        public static void getConstructor(Class<?> cls) throws Exception{
            //获得构造器
            Constructor<?>[] constructors = cls.getConstructors();
    //      Constructor<?>[] constructors = cls.getDeclaredConstructors();
            for(Constructor cts : constructors){
                System.out.println(cts.getName()+"-->"+cts.toString());
            }
    //输出:
    //      com.li.ref.StudentBean-->public com.li.ref.StudentBean()
    //      com.li.ref.StudentBean-->public com.li.ref.StudentBean(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
    //      com.li.ref.StudentBean-->public com.li.ref.StudentBean(java.lang.String)
    
            //获得默认无参构造方法
            Constructor ct = cls.getDeclaredConstructor(null);
            System.out.println(ct.toString());
            //获得只有一个参数的构造方法
            Constructor ct1 = cls.getDeclaredConstructor(new Class[]{String.class});
            System.out.println(ct1.toString()); //public com.li.ref.StudentBean(java.lang.String)
            //获得含有四个参数的构造方法
            Constructor ct4 = cls.getDeclaredConstructor(new Class[]{String.class, String.class, String.class, String.class});
            System.out.println(ct4.toString());
    
            //需要含有默认无参的构造方法
            StudentBean stu = (StudentBean) cls.newInstance();
            System.out.println(stu.toString());  //StudentBean [id=null, name=null, sex=null, age=null, height=null]
            //创建含一个参数的对象
            StudentBean st = (StudentBean) ct1.newInstance("25");
            System.out.println(st.toString());  //StudentBean [id=25, name=null, sex=null, age=null, height=null]
            //创建含四个参数的对象
            StudentBean st4 = (StudentBean) ct4.newInstance("1001","LiLei","male","16");
            System.out.println(st4.toString());  //StudentBean [id=1001, name=LiLei, sex=male, age=16, height=null]
        }
    
    
        /**
         * 获得类的属性
         */
        public static void getField(Class<?> cls) throws Exception{
            Field[] fields = cls.getDeclaredFields();
            for(Field fd : fields){
                fd.setAccessible(true);
                System.out.println(fd.toString());
            }
    //输出:       
    //      public java.lang.String com.li.ref.StudentBean.id
    //      public java.lang.String com.li.ref.StudentBean.name
    //      public java.lang.String com.li.ref.StudentBean.sex
    //      public java.lang.String com.li.ref.StudentBean.age
    //      private java.lang.String com.li.ref.StudentBean.height
    
            Field field = cls.getDeclaredField("id");
            System.out.println(field.toString());   //public java.lang.String com.li.ref.StudentBean.id
            StudentBean stu = (StudentBean) cls.newInstance();
            field.set(stu, "10010");
            System.out.println(stu.toString()); //StudentBean [id=10010, name=null, sex=null, age=null, height=null]
        }
    
    
    
        /**
         * 获取方法
         */
        public static void getMethod(Class<?> cls) throws Exception{
            Method[] methods = cls.getDeclaredMethods();
            for(Method method : methods){
                System.out.println(method.getName());
            }
    
            Method md = cls.getDeclaredMethod("goToSchool");
            md.setAccessible(true);
            StudentBean stu = (StudentBean) cls.newInstance();
            md.invoke(stu);
    
            Method method = cls.getDeclaredMethod("eat", String.class);
            method.invoke(stu, "vegetable");    //输出:eat vegetable
        }
    }
    

    坑爹的编辑器,看起来有点乱,聪明如你,肯定能看明白。

  • 相关阅读:
    swoole 的 go function 是什么
    MySQL grant之后要不要跟上 flush privileges
    操作数据库
    APP端异常情况
    评论列表优化联表问题
    tp5修改数据前过滤
    字典
    if语句
    【整理】android事件传递机制
    Linux常用操作
  • 原文地址:https://www.cnblogs.com/lishbo/p/9956058.html
Copyright © 2020-2023  润新知