zoukankan      html  css  js  c++  java
  • Java反射的简单入门

      1.Class的简单介绍

     Class类的类表示正在运行的Java应用程序中的类和接口。 枚举是一种类,一个注解是一种接口, 每个数组也属于一个反映为类对象的类,该对象由具有相同元素类型和维数的所有数组共享。 原始Java类型( booleanbytecharshortintlongfloatdouble ),和关键字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<Integer, String> map, String s) {
    
        }
    
        public Map<Integer, String> 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());
                }
            }            
        }
    
    }
  • 相关阅读:
    手机兼容性测试
    Monkey测试
    ADB常用指令
    ADB移动端测试
    关于虚拟网卡V1,V8的问题
    1
    排序算法
    查找算法
    二叉树的计算
    队列
  • 原文地址:https://www.cnblogs.com/dddyyy/p/10009678.html
Copyright © 2011-2022 走看看