Java Reflection

 

Class类事反射的源头

    @Test
    public void test2() {
        try{
            //调用构造器
            Class clazz = Person.class;
            Constructor cons = clazz.getConstructor(int.class, String.class);
            Person p = (Person)cons.newInstance(18, "May");
            System.out.println(p);

            //属性设置
            Field age = clazz.getDeclaredField("age");
            age.setAccessible(true);//调用私有的属性或者方法,需要先setAccessible()
            age.set(p,10);
            System.out.println(p);

            //调用方法
            Method setAge = clazz.getDeclaredMethod("setAge", int.class);
            setAge.invoke(p,11);
            System.out.println(p);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

 

 

  //获取Class实例的方式
    //Class 的实例就对应着一个运行时类
    //运行时类加载到内存中会缓存一定时间,在此时间之内,我们可以通过如下方式来获取运行时类。
    @Test
    public void test3() throws ClassNotFoundException {
        //方式一:调用运行时类的属性
        Class<Person> clazz1 = Person.class;
        System.out.println(clazz1);
        //方式二:通过运行时类的对象
        Person p1 = new Person();
        Class<? extends Person> clazz2 = p1.getClass();
        System.out.println(clazz2);
        //方式三:调用Class的静态方法:forName(String classPath)(常用)
        Class<?> clazz3 = Class.forName("com.atguigu.reflectionDemo.Person");
        System.out.println(clazz3);

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);
        //方式四:使用类的加载器:ClassLoader(了解)
        ClassLoader clazzLoader = ReflectionTest.class.getClassLoader();
        Class<?> clazz4 = clazzLoader.loadClass("Person");

    }

 

   //通过反射创建运行时类的对象
    @Test
    public void test1() throws IllegalAccessException, InstantiationException {
        Class clazz = Person.class;
        /*
        newInstance()调用此方法创建对应的运行时对象。内部调用了运行时类的空参构造器
        此当法正常地运行时类对象的要求:
        1.运行时类必须提供空参构造器
        2.空参构造器的访问权限要够,通常设置为public

        在Javabean中要求提供一个public的空参构造器,原因:
        1.便于通过反射,创建运行时类的对象
        2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器
         */
        Person p1 = (Person)clazz.newInstance();
        System.out.println(p1);

    }

 通过反射获取运行时类的属性

    //获取属性结构
    //getFields():获取当前运行时类及其父类中声明为public访问权限的属性
    @Test
    public void testField(){
        Class clazz = Person.class;
        Field[] fields = clazz.getFields();
        for(Field f:fields){
            System.out.println(f);
        }
    }
    //getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
    @Test
    public void testAllFields(){
        Class clazz =Person.class;
        Field[] fields = clazz.getDeclaredFields();
        for(Field f:fields){
            System.out.println(f);
        }
    }

 通过反射获取运行时类的方法

getMethods():获取当前运行时类及其父类中声明为public访问权限的方法

getDeclaredMethods():获取当前运行时类中声明的所有方法。(不包含父类中声明的方法)

 

getConstructors():获取当前运行时类及其父类中声明为public访问权限的构造方法

getDeclaredConstructors():获取当前运行时类中声明的所有构造方法。(不包含父类中声明的构造方法)

 

getGenericSuperClass():获取父类

还可以获取带泛型的父类泛型类型 

    public void test4() {
        Class clazz = Person.class;
        Type genericSuperclass = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) genericSuperclass;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
//        System.out.println(actualTypeArguments[0].getTypeName());
        System.out.println(((Class) actualTypeArguments[0]).getName());
    }

 

posted @ 2021-11-20 14:57  donkey8  阅读(29)  评论(0)    收藏  举报