zoukankan      html  css  js  c++  java
  • JAVA动态性之一一反射机制reflection

    
    
    package com.bjsxt.reflection.test.bean;
    
    public class User {
        private int id;
        private int age;
        private String uname;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getUname() {
            return uname;
        }
        public void setUname(String uname) {
            this.uname = uname;
        }
        public User(int id, int age, String uname) {
            super();
            this.id = id;
            this.age = age;
            this.uname = uname;
        }
        public User() {
            super();
            // TODO Auto-generated constructor stub
        }
        
    }
    
    
    package com.bjsxt.reflection.test;
    /**
     * 
     * 测试各种类型(class,interface,enum,annotation,primitive type,void)java。lang。Class对象获取方式
     * @author Administrator
     *
     */
    @SuppressWarnings("all")
    public class Demo01 {
        public static void main(String[] args) {
            String path = "com.bjsxt.reflection.test.bean.User";
            try {
                Class clazz = Class.forName(path);
                // 一个类被加载后 JVM就会创建一个该类的Class对象。类的结构信息会放大对应的Class对象中
                
                System.out.println(clazz.hashCode());
                
                
                Class clazz2 = Class.forName(path);
                System.out.println(clazz2.hashCode());//同一个类只有一个反射对象
                
                
                Class strClazz = String.class;
                Class strClazz2 = path.getClass();
                System.out.println(strClazz == strClazz2);
                
                Class intClazz = int.class;
                //数组  同样的数据类 比较是不是同一个维度 不同 则不同
                int[]arr01 = new int[10];
                int[]arr02 = new int[30];
                //2维数组
                int[][]arr03 = new int [3][3];
                System.out.println(arr01.getClass().hashCode());
                System.out.println(arr02.getClass().hashCode());
                System.out.println(arr03.getClass().hashCode());
                
                double[]arr04 = new double[10];
                System.out.println(arr04.getClass().hashCode());
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }
    1442002549
    1442002549
    true
    1383884648
    1383884648
    1701381926
    1381270477

    以上是如何获取

    各种类型(class,interface,enum,annotation,primitive type,void)java。lang。Class对象获取方式
    获取到对象后,下面利用反射里面的Api
    java.lang.reflect
    做些事情
    应用反射的API 获取类的信息(包的名字 类的名字 属性 方法  构造方法等)
     package com.bjsxt.reflection.test;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * 应用反射的API 获取类的信息(类的名字 属性 方法  构造方法等)
     * @author Administrator
     *
     */
    public class Demo02 {
        public static void main(String[] args) {
            String path = "com.bjsxt.reflection.test.bean.User";
            try {
                Class clazz = Class.forName(path);
                
                //获取包名+类名
                System.out.println(clazz.getName());
                // 获得类名 User
                System.out.println(clazz.getSimpleName());
                //获取属性信息            
                //引入import java.lang.reflect.Field;
                Field[] fields = clazz.getFields();//返回所有属性 public的属性 如何是别的 获取不到
                System.out.println(fields.length);//0
                Field[] fields1 = clazz.getDeclaredFields();//获得所有的属性 不管你的访问修饰符是什么
                System.out.println(fields.length);//3
                for(Field temp:fields){
                    System.out.println("属性"+temp);
                }
    //            Field f1 = clazz.getDeclaredField("id");
    //            Field f2 = clazz.getDeclaredField("age");
    //            Field f3 = clazz.getDeclaredField("uname");
                
                //获得 方法信息
                Method[] method = clazz.getDeclaredMethods();
                Method m =clazz.getDeclaredMethod("getUname", null);
                Method m2 = clazz.getDeclaredMethod("setUname", String.class);
                //获得构造放方法的信息
                Constructor[]constructors = clazz.getDeclaredConstructors();// 获得所有构造器
                Constructor c= clazz.getDeclaredConstructor(null);// 获得无参构造器
                Constructor c1= clazz.getDeclaredConstructor(int.class,int.class,String.class);
                //获得参数列表类型是int int String 方法的构造器
    
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        
        }
    
    }

     动态调用 获取到的 类的信息 (属性 方法 构造器)

    package com.bjsxt.reflection.test;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import com.bjsxt.reflection.test.bean.User;
    
    public class Demo03 {
        public static void main(String[] args) {
            String path = "com.bjsxt.reflection.test.bean.User";
            try {
                Class<User> clazz = (Class<User>)Class.forName(path);
                // 通过反射api调用构造方法 构造对象
                User u = clazz.newInstance(); //调用了 User的无参构造方法
                System.out.println(u);
                //调用有参构造器
                Constructor<User>c = clazz.getDeclaredConstructor(int.class,int.class,String.class);
                User u2 = c.newInstance(1001,18,"王二");
                System.out.println(u2.getUname());
                
                //通过反射api调用普通方法
                User u3 = clazz.newInstance();
                Method method =clazz.getDeclaredMethod("setUname", String.class);
                method.invoke(u3, "张三");//25 26 行代码 相等于  u3.setUname("张三");
                
                System.out.println(u3.getUname());
                
                // 通过反射api调用属性
                User u4 = clazz.newInstance();
                Field f = clazz.getDeclaredField("uname");
                f.setAccessible(true);//这个属性不用做安全检查了 可以直接访问  否则会报错 说不能访问私有属性
                f.set(u4, "李四");//通过反射直接写属性的值
                System.out.println(u4.getUname());//通过反射直接读属性的值
                System.out.println(f.get(u4));//通过反射读属性
                
    
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        
        
    
        }
    }

    反射机制的性能问题

    使用setAccessible提高性能(setAccessible是启用/禁用访问安全的开关)

    f.setAccessible(true);// 禁用安全检查 这个属性不用做安全检查了 可以直接访问  否则会报错 说不能访问私有属性

    效率提高4倍 

    反射操作注解(annotation)

    反正操作泛型(Generic)

    java采用泛型擦除的机制来引入泛型,也就是说,泛型仅仅是给编译器javac看的,来确保数据的安全性和免去数据类型转换,但是,一旦编译完成,所有和泛型相关的东西都被擦除,这一点也可以从类编译的class文件反编译看到。
     
    为了用反射操作泛型
    Java就新增了几种类型来代表不能被归一到Class类中的类型,但又和基本数据类型齐名的类型,通常使用的是前两个:
    • ParameterizedType:表示一种参数化的类型,比如Collection< String >
    • GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
    • TypeVariable:是各种类型变量的公共父接口
    • WildcardType:代表一种通配符类型表达式,比如?、? extends Number、? super Integer。(wildcard是一个单词:就是”通配符“)

    package com.bjsxt.reflection.test;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;
    import java.util.Map;
    
    import com.bjsxt.reflection.test.bean.User;
    
    public class Demo04 {
        //参数类型有泛型
        public void test01(Map<String,User>map,List<User>list){
            System.out.println("Demo04.test01()");        
        }
        // 无参 但是有返回值类型 泛型
        public Map<Integer,User> test02(){
            System.out.println("Demo04.test02()");
            return null;
        }
        //通过程序读取到 参数的泛型  和  返回值的泛型
        public static void main(String[] args) {
            try {
                //Demo04.class获得Demo04这个类的一个对象 
                //Demo04.class.getMethod("test01",Map.class,List.class);获得这个类的test01方法Method m这个对象        
                Method m = Demo04.class.getMethod("test01",Map.class,List.class);
                // m.getGenericParameterTypes();获得带泛型参数类型
                Type[]t = m.getGenericParameterTypes();
                for(Type paramType:t){
                    System.out.println("#"+paramType);
                    //判断是否参数类型是带有泛型
                    if(paramType instanceof ParameterizedType ){
                        //强制转换成带泛型的参数类型((ParameterizedType) paramType)
                        //.getActualTypeArguments();获得真正的带泛型参数类型
                        Type[]gernericTypes=((ParameterizedType) paramType).getActualTypeArguments();
                        for(Type genericType:gernericTypes){
                            System.out.println("泛型类型"+genericType);
                            
                        }
                    }
                }
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    #java.util.Map<java.lang.String, com.bjsxt.reflection.test.bean.User>
    泛型类型class java.lang.String
    泛型类型class com.bjsxt.reflection.test.bean.User
    #java.util.List<com.bjsxt.reflection.test.bean.User>
    泛型类型class com.bjsxt.reflection.test.bean.User
    
    
  • 相关阅读:
    CUDA C Best Practices Guide 在线教程学习笔记 Part 1
    0_Simple__simpleCallback
    0_Simple__simpleAtomicIntrinsics + 0_Simple__simpleAtomicIntrinsics_nvrtc
    0_Simple__simpleAssert + 0_Simple__simpleAssert_nvrtc
    0_Simple__matrixMulDrv
    0_Simple__matrixMulCUBLAS
    0_Simple__matrixMul + 0_Simple__matrixMul_nvrtc
    0_Simple__inlinePTX + 0_Simple__inlinePTX_nvrtc
    0_Simple__fp16ScalarProduct
    0_Simple__cudaOpenMP
  • 原文地址:https://www.cnblogs.com/PoeticalJustice/p/7678318.html
Copyright © 2011-2022 走看看