zoukankan      html  css  js  c++  java
  • java_reflect_01

    最近学习java开始接触到了框架,突然觉得java反射很重要,因此在这里做了一些总结(参考园中大苞米大神的文章)

    首先我们要认识一下Class:

    一、Class类有什么用?

       class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class,类型.getClass(),Class.forName("类名")等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class  对象。

    二、Class类的特征
        class类没有公有的构造方法,它由JVM自动调用(在new对象或者加载-classLoader时)

    三、Class类是Reflection API中核心的类,他位于java.lang.Class

    列出一些常用的方法。

    - getClassLoader():返回该类的加载器

    - forName(String className):返回与带有给定字符串名的类或接口相关联的 Class 对象

    - getDeclaredAnnotations():返回直接存在于此元素上的所有注释

    - getAnnotation(Class<A> annotationClass):如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

    - getAnnotations():返回此元素上存在的所有注释。

    - getName() : 获得类的完整名字

    - getFields() : 获得类的public类型的属性

    - getDeclaredFields() : 获得类的所有属性

    - getMethods() : 获得类的public类型的方法

    - getDeclaredMethods() : 获得类的所有方法

    - getMethod(String name, Class[] parameterTypes) : 获取类的特定方法(name参数指定方法名字,parameterTypes参数指定方法参数类型)

    - getConstructors() : 获得类的public类型的构造方法

    - getConstructor(Class[] parameterTypes) : 获得类的特定构造方法(parameterTypes参数指定构造方法的参数类型)

    - newInstance() : 通过类的不带参数的构造方法创建这个类的一个对象

    等等,具体可以参照API文档

    初步知识了Class以后,我们看看

    四、如何获取其对象class

    获取某个类或某个对象所对应的Class对象的常用的3种方法

    a) 使用Class类的静态方法forName:       

      Class.forName("java.lang.String");

    b) 使用类的.class语法: 

       String.class;

    c) 使用对象的getClass()方法(java.lang.Object类中的方法): 

       String s = "aa"; 

       Class<?> clazz = s.getClass();

    五、通过反射获取对象


    创建一个PO类

    package po;
    
    public class User {
        /**
         * id
         */
        private int id;
        /**
         * 年龄
         */
        private int age;
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 
         */
        public User() {
            super();
        }
        /**
         * @param id
         * @param name
         * @param age
         */
        public User(int id, String name, int age) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
        }
        /**
         * @return the age
         */
        public int getAge() {
            return age;
        }
        /**
         * @return the id
         */
        public int getId() {
            return id;
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param age the age to set
         */
        public void setAge(int age) {
            this.age = age;
        }
        /**
         * @param id the id to set
         */
        public void setId(int id) {
            this.id = id;
        }
        
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
        }
        
    }
    View Code

    大家都知道获得对象实例就是去new一个,其实就是调用对象的构造方法

    这里将调用构造方法参数的不同分为两种类型:

    a)调用无参数的构造方法:

    1.调用Class对象的newInstance()方法:

    @Test
        public void test01() throws Exception{
        Class<?> clazz=Class.forName("po.User");
        User newInstance =(User)clazz.newInstance();
        newInstance.setAge(24);
        newInstance.setId(1001);
        newInstance.setName("wangyang");
        System.out.println(newInstance);
        //User [id=1001, name=wangyang, age=24]
        
        }

    2.调用Class对象的Constructor对象的newInstance()方法,传递一个空的Class对象数组作为参数:

    @Test
        public void test01() throws Exception{
        Class<?> clazz=Class.forName("po.User");
        Constructor user=clazz.getConstructor(null);
        User u=(User) user.newInstance(null);
        u.setAge(24);
        u.setId(10);
        u.setName("wangyang");
        System.out.println(u);
            //User [id=10, name=wangyang, age=24]
    
        }

    b)调用有参数的构造方法:

    调用Class对象的Constructor对象的newInstance()方法,传递一个可变长的Class对象数组作为参数

    @Test
        public void test01() throws Exception{
        Class<?> clazz=Class.forName("po.User");
        Constructor        user=clazz.getConstructor(int.class,String.class,int.class);
        Object newInstance = user.newInstance(24,"wangyang",24);
        System.out.println(newInstance);
        //User [id=24, name=wangyang, age=24]
        }

    3.再来试一试反射调用方法

    @Test
        public void test01() throws Exception{
        Class<?> clazz=Class.forName("po.User");
        Object newInstance = clazz.newInstance();
        Method m=clazz.getMethod("setAge", int.class);
        Method m2=clazz.getMethod("toString", null);
        m.invoke(newInstance, 100);
        System.out.println(m2.invoke(newInstance, null));
        //User [id=0, name=null, age=100]
        }
  • 相关阅读:
    cf1131f 构造+并查集
    多源最短路小结
    bzoj2200拓扑排序+最短路+联通块
    cf478d 线性dp好题
    cf919D 线性dp+拓扑排序
    hiho1460 rmq模板题
    最小标示法模板 poj1509
    JAVA动态代理机制分析guide
    java动态代理(JDK和cglib)
    AOP面向切面编程
  • 原文地址:https://www.cnblogs.com/wangyang108/p/5667043.html
Copyright © 2011-2022 走看看