Java反射的简单入门

1.Class的简单介绍

Class类的类表示正在运行的Java应用程序中的类和接口。 枚举是一种类,一个注解是一种接口, 每个数组也属于一个反映为类对象的类,该对象由具有相同元素类型和维数的所有数组共享。 原始Java类型( boolean , byte , char , short , int , long , float和double ),和关键字void也表示为类对象。

  摘自jdk1.8中文版,刚开始看可能不懂,现在逐句来解释一下。

  第一句话:一个类被加载以后,JVM就会在内存中给创建一个对应类的Class对象。

  第二句话:类型相同的对象,维数相同的数组(不管长度)共享的是同一个内存中的Class对象。

  第三句话:上面这些原始的类型,也会在内存中有一个与之对象的Class对象。

package com.dingyu;import org.junit.Test;/** * Class的简单使用方法

*

* @author 70241

*

*/publicclass ClassDemo {

    @Test

    publicvoid classTest1() {

        try {

            Class class1 = Class.forName("com.dingyu.User");// 第一种获取Class对象的方法User user =new User();

            Class class2 = user.getClass();// 第二种获取Class对象的方法Class class3=User.class;//第三种获取Class对象的方法System.out.println("接下来判断到底同一类的不同对象的Class对象是不是同一个:"                    + (class1.hashCode() == class2.hashCode()&&class1.hashCode() == class3.hashCode()));

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

    @Test

    publicvoid classTest2() {

        String[] s1 =newString[10];

        String[] s2 =newString[30];

        String[][] s3 =newString[3][30];

        System.out.println(s1.getClass().hashCode()==s2.getClass().hashCode());

        System.out.println(s1.getClass().hashCode()==s3.getClass().hashCode());


    }

}

  2.Class获取类的属性,构造器,方法和注解的简单使用 

package com.dingyu;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import org.junit.Test;/** * Class的简单用法

*

* @author dingyu

*

*/publicclass ClassDemo02 {

    @Test

    publicvoidusingClass()throws Exception {

        Class userClass = Class.forName("com.dingyu.User");

        // 获得类名System.out.println(userClass.getName());// 获得全类名System.out.println(userClass.getSimpleName());// 获得类名

        // 获得属性Field[] fields = userClass.getDeclaredFields();// 获得所有的属性for (Field field : fields) {

            System.out.println(field.getName());

        }

        System.out.println(userClass.getDeclaredField("id").getName());// 获得指定的属性

        // 获得方法Method[] methods = userClass.getDeclaredMethods();// 获得所有的方法for (Method method : methods) {

            System.out.println(method.getName());

        }

        Method method = userClass.getDeclaredMethod("setId",int.class);// 获得指定的方法,前面方法名,后面方法的参数        System.out.println(method.getName());

        // 获得构造器Constructor[] constructors = userClass.getDeclaredConstructors();

        System.out.println(constructors.length);

        Constructor constructor = userClass.getDeclaredConstructor(int.class, String.class,int.class);// 获得指定的构造器,需要指定构造的参数        System.out.println(constructor.getName());

        // 获得注解Annotation[] annotations = userClass.getAnnotations();

        for (Annotation annotation : annotations) {

            System.out.println(annotation);

        }

        // 指定注解名MyAnnotation annotation = (MyAnnotation)userClass.getDeclaredAnnotation(MyAnnotation.class);

        System.out.println(annotation);

    }

}

  3.Class动态的调用构造器,方法,修改属性 

package com.dingyu;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import org.junit.Test;/** * 使用反射动态的调用构造器,方法,修改属性

* @author 70241

*

*/publicclass ClassDemo03 {

    @Test

    @SuppressWarnings("all")

    publicvoidusingClass()throws Exception {

        Class class1 = Class.forName("com.dingyu.User");


        //使用反射去调用构造器User user1 = (User) class1.newInstance();//调用的是无参的       

        Constructor constructor = class1.getDeclaredConstructor(int.class,String.class,int.class);//获得有参的构造器User user2 = (User) constructor.newInstance(04,"dingyu",20);//动态生成对象


        //使用反射去调用方法Method methodSetId = class1.getDeclaredMethod("setId",int.class);

        methodSetId.invoke(user1, 02);//执行user1中的setId,后面是给的参数        System.out.println(user1.getId());


        //使用反射去修改属性的值Field field = class1.getDeclaredField("age");

        field.setAccessible(true);//因为age是私有的,加上这句就表示这个属性不需要做安全检查field.set(user1, 20);

        System.out.println(field.get(user1));

        System.out.println(user1.getAge());




    }

}

  4.反射获得带泛型的参数或返回值里泛型的的类型

package com.dingyu;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.Map;/** * 反射获得带泛型的参数或返回值里泛型的的类型

* @author dingyu

*

*/publicclass ClassDemo04 {

    publicvoidtest01(Map map, String s) {

    }

    publicMap test02() {

        returnnull;

    }

    publicstaticvoidmain(String[] args)throws Exception {

        //参数中带泛型的Method method = ClassDemo04.class.getDeclaredMethod("test01", Map.class, String.class);

        Type[] types = method.getGenericParameterTypes();// 返回一个 Type对象的数组, Type以声明顺序表示由该对象表示的可执行文件的形式参数类型

        // 打印这些参数的类型for (Type type : types) {

            System.out.println(type.getTypeName());

            if(typeinstanceofParameterizedType) {// 如果是泛型的参数Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型for (Type type2 : actualTypeArguments) {

                    System.out.println(type2.getTypeName());

                }

            }

        }


        //返回值中带泛型的Method method02 = ClassDemo04.class.getDeclaredMethod("test02");

        Type type = method02.getGenericReturnType();// 返回的类型

        // 打印这些返回的类型                    System.out.println(type.getTypeName());

        if(typeinstanceofParameterizedType) {// 如果是泛型的参数Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型for (Type type2 : actualTypeArguments) {

            System.out.println(type2.getTypeName());

            }

        }           

    }

}

欢迎工作一到八年的Java工程师朋友们加入Java高级交流群:828697593

本群提供免费的学习指导 架构资料 以及免费的解答

不懂得问题都可以在本群提出来 之后还会有直播平台和讲师直接交流噢

哦对了,喜欢就别忘了关注一下哦~

你可能感兴趣的:(Java反射的简单入门)