美文网首页程序员
Java反射的简单入门,一分钟简单小课堂

Java反射的简单入门,一分钟简单小课堂

作者: 程序员理想 | 来源:发表于2018-11-26 15:07 被阅读7次

    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 * */public class ClassDemo {

        @Test    public void 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    public void classTest2() {

    String[] s1 = new String[10];

    String[] s2 = new String[30];

    String[][] s3 = new String[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 * */public class ClassDemo02 {  

    @Test    public void usingClass() 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 * */

    public class ClassDemo03 {

      @Test    @SuppressWarnings("all")

        public void usingClass() 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 * */public class ClassDemo04 {

      public void test01(Map map, String s) {

        }

        public Map test02()

    {        return null;

        }

        public static void main(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 (type instanceof ParameterizedType) {

    // 如果是泛型的参数

                    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 (type instanceof ParameterizedType) {// 如果是泛型的参数

              Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型

                for (Type type2 : actualTypeArguments) {            System.out.println(type2.getTypeName());

                }

          }

                  }}

    原作者:DingYu

    原文:https://www.cnblogs.com/dddyyy/p/10009678.html

    相关文章

      网友评论

        本文标题:Java反射的简单入门,一分钟简单小课堂

        本文链接:https://www.haomeiwen.com/subject/xysbqqtx.html