• java反射基础


     1 package com.demo.bean;
     2 
     3 import java.util.Date;
     4 
     5 public class User {
     6     public String name;
     7     private int age;
     8     
     9     public User() {}
    10     
    11     public User(String name, int age) {
    12         super();
    13         this.name = name;
    14         this.age = age;
    15     }
    16     
    17     public String getName() {
    18         return name;
    19     }
    20     public void setName(String name) {
    21         this.name = name;
    22     }
    23     public int getAge() {
    24         return age;
    25     }
    26     public void setAge(int age) {
    27         this.age = age;
    28     }    
    29     public String show() {
    30         return "User [name=" + name + ", age=" + age + "]";
    31     }
    32     
    33 }
    用来反射的对象 User
    1             User u = new User();2             Class clazz01 = Class.forName("com.demo.bean.User");
    3             Class clazz02 = u.getClass();
    4             Class clazz03 = u.class;

    通过class获得类名,属性,方法,构造器对象

           Class clazz = Class.forName("com.demo.bean.User");
           // 包名+类名 Class className = clazz.getName();
    // 类名 String simpleName = clazz.getSimpleName(); // 返回一个public 的属性对象 Field Field nameField = clazz.getField("name"); // 返回包含所有的public 属性数组 Field[] Field[] fields = clazz.getFields(); // 返回一个 的属性对象 Field(包括private) Field pwdField = clazz.getDeclaredField("age"); // 返回包含所有的 属性数组(包括private) Field[] declaredFields = clazz.getDeclaredFields(); // 通过方法名字和参数获得方法对象 Method method = clazz.getDeclaredMethod("getAge"); Method method02 = clazz.getDeclaredMethod("setAge",int.class); // 获得所有方法 Method[] methods = clazz.getDeclaredMethods(); // 通过参数获得构造器对象 Constructor ctr01 = clazz.getDeclaredConstructor(); Constructor ctr02 = clazz.getDeclaredConstructor(String.class,int.class); // 获得所有构造器对象 Constructor[] ctrs = clazz.getDeclaredConstructors(); // 产生无参数构造,javabean必须要有无参数构造 User use02 = (User) clazz.newInstance();

    反射生成对象和调用方法

    package com.demo.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    import com.demo.bean.User;
    
    public class Demo01 {
        
        public static void main(String[] args) throws Exception {
            
                Class clazz = User.class;
                // 无参对象
                User u1 = (User) clazz.newInstance();
                // 有参对象
                Constructor ctr = clazz.getDeclaredConstructor(String.class,int.class);
                User u2 = (User) ctr.newInstance("ouyangri",21);
                
                // 获得setName,并调用
                Method method02 = clazz.getDeclaredMethod("setName",String.class);
                method02.invoke(u2,"小红");
                // 获得getName,并调用
                Method method = clazz.getDeclaredMethod("getName");
                // 私有方法必须设置为可访问
                method.setAccessible(true);
                String name = (String) method.invoke(u2);
                
                // 获得属性
                Field f = clazz.getDeclaredField("age");
                // 私有属性必须设置为可访问
                f.setAccessible(true);
                // 设置属性值
                f.set(u2, 24);
                // 获得属性值
                int age = (int) f.get(u2);
            
        }
    }

    注意: 如果需要频繁的用反射访问属性或者方法,应该设置 setAccessible(true),减少安全性检查,提高效率。

    package com.demo.reflect;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.TypeVariable;
    
    import com.demo.bean.User;
    
    public class Demo01 {
        public static void main(String[] args) throws Exception {
            for(int i = 0;i < 5;i++)
            {
                test01();//普通方法调用
                test02();// 安全行检查反射方法调用
                test03();// 无安全行检查,反射方法调用
                System.out.println("#######################################");
            }
        }
        
        // 普通方法调用
        public static void test01() {
            long start = System.currentTimeMillis();
            User u = new User();
            for(int i = 0;i < 1000000000L;i++)
                u.getName();
            long end = System.currentTimeMillis();
            System.out.println("普通方法调用:执行十亿次: "+(double)(end-start)/1000);
        }
        // 安全行检查反射方法调用
        public static void test02() throws Exception{
            long start = System.currentTimeMillis();
            User u = new User();
            Method method = u.getClass().getMethod("getName");
            for(int i = 0;i < 1000000000;i++)
                method.invoke(u);
            long end = System.currentTimeMillis();
            System.out.println("安全行检查反射方法调用:执行十亿次: "+(double)(end-start)/1000);
        }
        // 无安全行检查,反射方法调用
        public static void test03() throws Exception{
            long start = System.currentTimeMillis();
            User u = new User();
            Method method = u.getClass().getMethod("getName");
            method.setAccessible(true);
            
            for(int i = 0;i < 1000000000;i++)
                method.invoke(u);
            long end = System.currentTimeMillis();
            System.out.println("无安全行检查,反射方法调用:执行十亿次: "+(double)(end-start)/1000);
        }
    }
    效率对比

    Console:

    普通方法调用:执行十亿次: 0.352
    安全性检查反射方法调用:执行十亿次: 1.422
    无安全性检查,反射方法调用:执行十亿次: 0.833
    #######################################
    普通方法调用:执行十亿次: 0.354
    安全性检查反射方法调用:执行十亿次: 1.384
    无安全性检查,反射方法调用:执行十亿次: 0.817
    #######################################
    普通方法调用:执行十亿次: 0.353
    安全性检查反射方法调用:执行十亿次: 1.253
    无安全性检查,反射方法调用:执行十亿次: 0.678
    #######################################
    普通方法调用:执行十亿次: 0.346
    安全性检查反射方法调用:执行十亿次: 1.233
    无安全性检查,反射方法调用:执行十亿次: 0.678
    #######################################
    普通方法调用:执行十亿次: 0.343
    安全性检查反射方法调用:执行十亿次: 1.24
    无安全性检查,反射方法调用:执行十亿次: 0.689
    #######################################

    反射操作泛型(generic)

    Type  是Java编程语言中所有类型的通用超级接口。 这些包括原始类型,参数化类型,数组类型,类型变量和原始类型。

    ParameterizedType  表示一个参数化类型,如Collection <String>。

    GenericArrayType  表示参数化类型或类型变量的数组类型。

    package com.demo.reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.Map;
    
    public class Demo01 {
        
        public static void main(String[] args) throws Exception {
            
            //test01();
            //test02();
            //test03();
        }
        // 获得方法参数下的参数化类型
        static void test01() throws Exception {
            Class clazz = Class.forName("com.demo.reflect.GenericTest");
            GenericTest gt = (GenericTest) clazz.newInstance();
            Method method = clazz.getMethod("test01",Map.class,LinkedList.class,String.class);
            // 获取test01方法下所有的参数化类型 参数
            Type[] genericParameterTypes = method.getGenericParameterTypes();
            
            for(Type t:genericParameterTypes) {
                // 如果是参数化类型,就打印
                if(t instanceof ParameterizedType) {
                    ParameterizedType ptype = (ParameterizedType) t;
                    System.out.println("参数化类型:"+ptype.getTypeName());
                    // 获取参数化类型下所有的 具体类型
                    Type[] actualTypeArguments = ptype.getActualTypeArguments();
                    for(Type tt:actualTypeArguments) {
                        System.out.println("	"+tt.getTypeName());
                    }
                
                }
            }
            
            
        }
        // 获得方法返回值的参数化类型
        static void test02() throws Exception {
            Class clazz = Class.forName("com.demo.reflect.GenericTest");
            GenericTest gt = (GenericTest) clazz.newInstance();
            Method method = clazz.getMethod("test01",Map.class,LinkedList.class,String.class);
            // 获取test01方法返回值下所有的参数化类型 参数
            Type t = method.getGenericReturnType();
            if(t instanceof ParameterizedType) {
                ParameterizedType ptype = (ParameterizedType) t;
                System.out.println("参数化类型:"+ptype.getTypeName());
                // 获取参数化类型下所有的 具体类型
                Type[] actualTypeArguments = ptype.getActualTypeArguments();
                for(Type tt:actualTypeArguments) {
                    System.out.println("	"+tt.getTypeName());
                }
            }
        }
        // 获得属性的参数化类型
        static void test03() throws Exception {
            Class clazz = Class.forName("com.demo.reflect.GenericTest");
            GenericTest gt = (GenericTest) clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            
            for(Field f:fields) {
                f.setAccessible(true);
                if(f.getGenericType() instanceof ParameterizedType) {
                    ParameterizedType ptype = (ParameterizedType) f.getGenericType();
                    System.out.println(ptype.getTypeName());
                    // 获取参数化类型下所有的 具体类型
                    Type[] actualTypeArguments = ptype.getActualTypeArguments();
                    for(Type tt:actualTypeArguments) {
                        System.out.println("	"+tt.getTypeName());
                    }
                }
            }
        }
        
        
    }
    
    
    class GenericTest{
        private HashMap<String,Integer> map;
        private LinkedList<Double> list;
        GenericTest(){};
        public Map<String,Integer> test01(Map<String,Integer> map,LinkedList<Double> list,String str) {
            return null;
        };
    }

     反射操作注解

    package com.demo.reflect;
    
    import java.lang.annotation.Annotation;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.lang.reflect.Field;
    
    @SuppressWarnings("all")
    public class Demo03 {
        public static void main(String[] args) throws Exception{
            
            Class clazz = Class.forName("com.demo.reflect.User");
            User u = (User) clazz.newInstance();
            System.out.println("############## 获得类上所有的注解##############");
            // 获得类上所有的注解
            Annotation[] annotations = clazz.getAnnotations();
            for(Annotation an : annotations) {
                System.out.println(an);
            }
            System.out.println("############## 获得类上指定名称的注解##############");
            // 获得类上指定名称的注解
            Myannotation myat = (Myannotation) clazz.getAnnotation(Myannotation.class);
            String tableName = myat.value();
            System.out.println("tableName: "+tableName);
            
            
            // 获得指定名称字段的注解
            System.out.println("##############获得指定名称字段的注解###############");
            Field field = clazz.getDeclaredField("username");
            Myannotation myat02 = field.getAnnotation(Myannotation.class);
            System.out.println("columnName: "+myat02.columnName());
            System.out.println("type: "+myat02.type());
            System.out.println("length: "+myat02.length());
            
            // 获得字段下所有的注解
            System.out.println("##############获得字段下所有的注解###############");
            Field[] fields = clazz.getDeclaredFields();
            for(Field f : fields) {
                Myannotation myat03 = f.getAnnotation(Myannotation.class);
                System.out.println("columnName: "+myat03.columnName());
                System.out.println("type: "+myat03.type());
                System.out.println("length: "+myat03.length());
            }
    
            
            
        }
    }
    
    // 元注解@Target,描述注解可以作用的范围
    @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
    //    元注解@@Retention,描述注解保留时期
    @Retention(RetentionPolicy.RUNTIME)
    @interface Myannotation {
        /*
             格式: 
                类型   属性名() [default 属性值]
         */
        String columnName() default "";
        
        String type() default "";
        
        // 带有默认值可以不进行赋值操作
        int length() default -1;
        
        /*
         如果属性是 value 默认不通过属性名赋值  
        ex: 
            Myannotation("xxxx") == Myannotation(value="xxxx")
         */
        String value() default "";
    }
    
    
    @Myannotation("user")
    class User{
        @Myannotation(columnName="username",type="varchar",length=20)
        private String username;
        @Myannotation(columnName="pwd",type="varchar",length=20)
        private String pwd;
        
        public User() {
            super();
        }
    
        public User(String username, String pwd) {
            super();
            this.username = username;
            this.pwd = pwd;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
        
    }
  • 相关阅读:
    GIT学习实践笔记
    ubuntu 安装pygit2
    强化vim打造python的IDE
    Python Django学习和实践
    浏览器调试工具网页性能分析中的使用
    公司发版shell脚本重构
    Nightwatch+gulp
    Git
    JavaScript Unit Test with Qunit
    Unit Test Mocking Framework
  • 原文地址:https://www.cnblogs.com/rainouyang/p/10765454.html
Copyright © 2020-2023  润新知