zoukankan      html  css  js  c++  java
  • Java反射总结

    反射(java.lang.reflect)用于分析类能力

    (一)Class类

    1.定义

    Java运行时为每一个对象都维护的一个类型标识,用于跟踪对象所属的类提供给虚拟机分析调用,而保存这些信息的类就是Class类

    (一个Class类对象可以理解为一个类型,这个类型可以是类或基本数据类型int等)

    2.作用

    通过对象所属的Class类,我们可以获取对象类型的数据域,方法,父类等一切类信息,还可以用它来创建实例对象

    获得父类

                //2.获取父类
                Class superc1=c1.getSuperclass();

    创建实例

            //利用反射创建一个实例对象
            Class myClass=Class.forName("java.util.Random");
            Random random=(Random)myClass.newInstance();    

    3.获得Class类的3种途径

    1. 调用Class的静态方法获取:Class.forName(String className)
    2. 对象调用getClass()方法获取Class
    3. 通过类型名.class获取,如T.class,T可以是基本数据类型int等,也可以是具体的类如Random.class
            Class myClass=Class.forName("java.util.Random");
            myClass=new Random().getClass();
            myClass=Random.class;

    (二)用于描述一个class的三个类:Field,Method,Constructor

    Field类代表一个class中的数据域

    Method类代表一个class中的方法

    Constructor类代表一个class中的构造器

    这三个类都继承Accessible

    1.获取一个类中的Field,Method,Constructor

    Class类调用getDeclaredFields()方法获得该类的所有数据域

    Class类调用getDetclaredMethods()方法获得该类的所有方法

    Class类调用getDetclaredConstructors()方法获得该类的构造器

    2.获得一个Class|Field|Method|Constructor的修饰符

                //Modifier.toString()能够获取c1的修饰符public final
                String modifiers=Modifier.toString(c1.getModifiers());        

    调用这四个类的getModifiers()方法可以返回一个int,作为参数传入Modifier.toString(),该方法会根据int判断出修饰符

    3.获得Field数据域的类型(Class)与Field的名称

                Class classType=f.getType();
                String name=f.getName();

    4.获取Method的返回类型,Method名称,Method参数类型

                String returnType=methods[j].getReturnType().getName();
                String methodName=methods[j].getName();
                Class[] paraTypes=methods[j].getParameterTypes();

    5.打印一个类的具体信息

    package Reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    /**
     * @ClassName ReFlectionTest
     * @Description 利用反射打印Double类的所有方法
     * @Author cherry
     * @Date 2018/6/9 21:22
     * @Update 2018/6/9 21:22
     **/
    public class ReFlectionTest{
        public static void main(String[] argv){
            String className="java.lang.Double";
            try{
                //1.获取Class
                Class c1=Class.forName(className);
                //2.获取父类
                Class superc1=c1.getSuperclass();
                //3.Modifier.toString()能够获取c1的属性public final
                String modifiers=Modifier.toString(c1.getModifiers());
                //4.打印c1的属性
                if(modifiers.length()>0)System.out.print(modifiers+" ");
                //5.打印c1的类名
                System.out.print("class "+className);
                //6.若有继承则打印
                if(superc1!=null&&superc1!=Object.class)System.out.print("extends "
                        +superc1.getName());
                //7.打印中括号
                System.out.print("
    {
    ");
                //8.打印域
                printFields(c1);
                //9.打印构造器
                printConstructors(c1);
                //10.打印方法
                printMethods(c1);
                //11.打印中括号
                System.out.print("
    }
    ");
            }catch(ClassNotFoundException e){
                e.printStackTrace();
            }
        }
    
        /**
         * 打印域
         * @param c1
         */
        public static void printFields(Class c1){
            //1.获得所有域
            Field[] fields=c1.getFields();
            //2.遍历打印
            for(Field f:fields){
                Class classType=f.getType();
                String name=f.getName();
                //3.打印进位符
                System.out.print("   ");
                //4.打印属性
                String modifiers=Modifier.toString(f.getModifiers());
                if(modifiers.length()>0)System.out.print(modifiers+" ");
                System.out.println(classType+" "+name+";");
            }
            System.out.println();
        }
    
        /**
         * 打印传入类的构造器
         * @param c1
         */
        public static void printConstructors(Class c1){
            //1.获取所有构造器
            Constructor[] constructors=c1.getConstructors();
            //2.遍历打印
            for(Constructor c:constructors){
                //3.打印tab占位符
                System.out.print("   ");
                //4.获取构造器的属性
                String modifier=Modifier.toString(c.getModifiers());
                if(modifier.length()>0)System.out.print(modifier+" ");
                //5.打印构造器名
                String conName=c.getName();
                System.out.print(conName+"(");
                //6.打印参数
                Class[] paraTypes=c.getParameterTypes();
                for(int j=0;j<paraTypes.length;j++){
                    if(j>0)System.out.print(", ");
                    System.out.print(paraTypes[j].getName());
                }
                System.out.print(");
    ");
            }
            System.out.print("
    ");
        }
    
        /**
         * 打印方法
         * @param c1
         */
        public static void printMethods(Class c1){
            //1.获取所有的方法
            Method[] methods=c1.getMethods();
            //2.遍历打印
            for(int j=0;j<methods.length;j++){
                //3.打印占位符
                System.out.print("   ");
                //4.打印方法属性
                String modifiers=Modifier.toString(methods[j].getModifiers());
                if(modifiers.length()>0)System.out.print(modifiers+" ");
                //5.打印返回类型
                String returnType=methods[j].getReturnType().getName();
                System.out.print(returnType+" ");
                //6.打印方法名
                String methodName=methods[j].getName();
                System.out.print(methodName+"(");
                //7.打印参数名
                Class[] paraTypes=methods[j].getParameterTypes();
                for(int i=0;i<paraTypes.length;i++){
                    if(i>0)System.out.print(",");
                    System.out.print(paraTypes[i].getName());
                }
                if(j+1!=methods.length) System.out.print(")
    ");
            }
        }
    }

     

    (三)运行时获取一个对象的数据域的具体值

            Student student=new Student(18);                        //创建student对象
            Class studentClass=student.getClass();                  //获取Student的Class
            Field field=studentClass.getDeclaredField("age");       //得到age域
            field.setAccessible(true);                              //设置可访问private域
            System.out.println(field.get(student));                 //访问age域的值

     

    (四)调用一个对象的方法

            Student student=new Student(18);                                   //创建student对象
            Class studentClass=student.getClass();                            //获取Student的Class
            Method setAgeMethod=studentClass.getMethod("setAge", int.class);       //获取方法
            setAgeMethod.invoke(student,20);                                 //访问age域的值
            System.out.println(student.getAge());                               //返回20

     

    (五)实现一个泛型数组操作方法

        /**
         * 用于扩展已经填满的数组
         * @param a
         * @param newLength
         * @return
         */
        public static Object goodCopyOf(Object a,int newLength){
            Class c1=a.getClass();                          //获取传入的a的Class
            if(!c1.isArray())return null;                   //若不是数组类型直接返回null
            Class compomentType=c1.getComponentType();      //获取数组元素类型
            int length=Array.getLength(a);                  //获取传入的数组的长度
            Object newArray=Array.newInstance(compomentType,newLength);       //Array.newInstance()根据元素类型与长度新建一个相同类型数组且长度扩大              
            System.arraycopy(a,0,newArray,0,Math.min(length,newLength));      //将原数组的值赋予新数组
            return newArray;
        }

    参考《Java核心技术 卷I》p190

  • 相关阅读:
    Vue路由跳转时修改页面标题
    Vue整合Quill富文本编辑器
    XML中的转义字符
    整合SSM框架环境搭建
    Android搞定权限申请
    Android实现秒开效果
    tail -f 与tail -F的区别
    druid 启动报错
    sqoop flume学习笔记
    20180911
  • 原文地址:https://www.cnblogs.com/ming-szu/p/9162466.html
Copyright © 2011-2022 走看看