博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java反射机制及API使用
阅读量:6936 次
发布时间:2019-06-27

本文共 9853 字,大约阅读时间需要 32 分钟。

反射简单来说,就是动态加载对象,并对对象进行剖析。在Java中的反射机制是指在运行状态中,对于任意一个类,都能够知道并获取这个类的所有属性和方法。

Java反射机制的作用:

  • 在运行时判断任意一个对象所属的类。
  • 在运行时判断任意一个类所具有的成员变量和方法。
  • 在运行时任意调用一个对象的方法
  • 在运行时构造任意一个类的对象

反射机制的优缺点是什么?

反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性。

它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它

满足我们的要求。这类操作总是慢于只直接执行相同的操作。

获取Class对象的三种方式

package com.gyl;public class Student {    public int no;    public String sex;    private String name;    private int age;        public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    /*     * 构造方法     */       Student(String str){         System.out.println("(默认)的构造方法 s = " + str);     }          //无参构造方法     public Student(){         System.out.println("调用了公有、无参构造方法执行了。。。");     }          //有一个参数的构造方法     protected Student(char name){         System.out.println("姓名:" + name);     }          //有多个参数的构造方法     public Student(String name ,int age){         System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。     }          //私有构造方法     private Student(int age){         System.out.println("私有的构造方法   年龄:"+ age);     }    }
package com.gyl;import java.lang.reflect.Constructor;public class Main {    public static void main(String[] args) throws ClassNotFoundException {        Student student = new Student();                /*         * JAVA反射--获取Class对象的三种方式         */                // 通过对象名.getClass()方法获取        Class stuClass = student.getClass();        System.out.println("stuClass is "+stuClass.getName());                        // 通过类名.class方式获得        Class stuClass1 = Student.class;        System.out.println("stuClass1 is "+stuClass1.getName());        System.out.println(stuClass == stuClass1);                // 通过Class.forName()方法获得        Class stuClass2 = Class.forName("com.gyl.Student");        System.out.println("stuClass2 is "+stuClass2);        System.out.println(stuClass1 == stuClass2);    }}Output:stuClass is com.gyl.StudentstuClass1 is com.gyl.StudenttruestuClass2 is class com.gyl.Studenttrue
在运行期间,一个类,只有一个Class对象产生。三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都选第三种,一个字符串可以传入也可写在配置文件中等多种方法。

反射API

获取构造方法

// 返回指定参数类型 public的构造器。 Constructor
getConstructor(类
... parameterTypes) // 返回指定参数类型的构造器(public, protected, private)。Constructor
getDeclaredConstructor(类
... parameterTypes) // 返回所有的public类型的构造器Constructor
[] getConstructors() // 返回所有的构造器Constructor
[] getDeclaredConstructors()
package com.gyl;import java.lang.reflect.Constructor;public class Main {    public static void main(String[] args) throws ClassNotFoundException {        // 通过Class.forName()方法获得Class对象        Class stuClass = Class.forName("com.gyl.Student");                        System.out.println("************返回所有public构造方法************");        Constructor[] constructors = stuClass.getConstructors();        for (Constructor constructor : constructors) {            System.out.println(constructor);        }        /*         * Output:         * ************返回所有public构造方法************         *    public com.gyl.Student()         *    public com.gyl.Student(java.lang.String,int)         */            System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");          Constructor[] constructors2 = stuClass.getDeclaredConstructors();        for (Constructor constructor : constructors2) {            System.out.println(constructor);        }        /*         * Output:         * ************所有的构造方法(包括:私有、受保护、默认、公有)***************         *    private com.gyl.Student(int)         *    public com.gyl.Student()         *    protected com.gyl.Student(char)         *    public com.gyl.Student(java.lang.String,int)         *    com.gyl.Student(java.lang.String)         */                        Constructor constructor;        System.out.println("************返回指定类型的 public构造器************");        try {            constructor = stuClass.getConstructor(String.class, int.class);            System.out.println(constructor);        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (SecurityException e) {            e.printStackTrace();        }        /*         * Output:         * ************返回指定类型的 public构造器************         * public com.gyl.Student(java.lang.String,int)         *          * 如果指定参数的构造器是非public类型的 则抛出java.lang.NoSuchMethodException异常         */                  System.out.println("************返回指定类型的构造器************");        try {             constructor = stuClass.getDeclaredConstructor(int.class);            System.out.println(constructor);            // char.class        } catch (NoSuchMethodException e) {             // String.class, int.class            e.printStackTrace();        } catch (SecurityException e) {            e.printStackTrace();        }        /*         * Output:         * ************返回指定类型的构造器************         * public com.gyl.Student(java.lang.String,int)         * protected com.gyl.Student(char)         * private com.gyl.Student(int)         */    }}

获取变量

// 根据变量名获得对应的变量,访问权限不限;Field getDeclaredField(String name) // 获得类中所有属性变量 Field[] getDeclaredFields()// 根据变量名获取对应public类型的属性变量Field getField(String name) // 获取类中所有public类型的属性变量Field[] getFields()
package com.gyl;import java.lang.reflect.Field;public class Main {    public static void main(String[] args) throws ClassNotFoundException {        // 通过Class.forName()方法获得Class对象        Class stuClass = Class.forName("com.gyl.Student");                try {            Field field1 = stuClass.getField("sex");            System.out.println(field1);                        Field field = stuClass.getDeclaredField("name");            System.out.println(field);        } catch (NoSuchFieldException e) {            e.printStackTrace();        } catch (SecurityException e) {            e.printStackTrace();        }        /*         * Output:         * public java.lang.String com.gyl.Student.sex         * private java.lang.String com.gyl.Student.name         * 如果使用getField方法指定了一个非public类型的属性,则抛出java.lang.NoSuchFieldException异常         */                Field[] fields1 = stuClass.getFields();        Field[] fields = stuClass.getDeclaredFields();        System.out.println("************返回所有public属性************");        for (Field field : fields1) {            System.out.println(field);        }        /*         * Output:         * ************返回所有public属性************         *    public int com.gyl.Student.no         *    public java.lang.String com.gyl.Student.sex         */        System.out.println("************返回所有属性************");        for (Field field : fields) {            System.out.println(field);        }        /*         * Output:         * ************返回所有属性************         *    public int com.gyl.Student.no         *    public java.lang.String com.gyl.Student.sex         *    private java.lang.String com.gyl.Student.name         *    private int com.gyl.Student.age         */    }}

获取方法

// 获取“名称是name,参数是parameterTypes”的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method  getMethod(String name, Class[] parameterTypes)// 获取全部的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method[]  getMethods()// 获取“名称是name,参数是parameterTypes”,并且是类自身声明的函数,包含public、protected和private方法。public Method  getDeclaredMethod(String name, Class[] parameterTypes)// 获取全部的类自身声明的函数,包含public、protected和private方法。public Method[]  getDeclaredMethods()// 如果这个类是“其它类中某个方法的内部类”,调用getEnclosingMethod()就是这个类所在的方法;若不存在,返回null。public Method  getEnclosingMethod()
package com.gyl;import java.lang.reflect.Method;public class Main {    public static void main(String[] args) throws ClassNotFoundException {        // 通过Class.forName()方法获得Class对象        Class stuClass = Class.forName("com.gyl.Student");                Method method;        try {//            method = stuClass.getMethod("getName");            method = stuClass.getDeclaredMethod("getAge");            System.out.println(method);        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (SecurityException e) {            e.printStackTrace();        }                        System.out.println("*********输出所有方法********");        Method[] methods = stuClass.getDeclaredMethods();        for (Method method2 : methods) {            System.out.println(method2);        }        /*         * Output:         * public int com.gyl.Student.getAge()         *    *********输出所有方法********         *    public java.lang.String com.gyl.Student.getName()         *    public void com.gyl.Student.setName(java.lang.String)         *    void com.gyl.Student.print(java.lang.String)         *    public int com.gyl.Student.getAge()         *    public void com.gyl.Student.setAge(int)         */    }}

通过反射越过泛型检查

泛型用在编译期,编译过后泛型擦除(消失掉)。所以是可以通过反射越过泛型检查的

import java.lang.reflect.Method;  import java.util.ArrayList;   /* * 通过反射越过泛型检查 *  * 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值? */  public class Demo {     public static void main(String[] args) throws Exception{         ArrayList
strList = new ArrayList<>(); strList.add("aaa"); strList.add("bbb"); // strList.add(100); //获取ArrayList的Class对象,反向的调用add()方法,添加数据 Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象 //获取add()方法 Method m = listClass.getMethod("add", Object.class); //调用add()方法 m.invoke(strList, 100); //遍历集合 for(Object obj : strList){ System.out.println(obj); System.out.println(obj.getClass()); } /* *Output: * aaa * class java.lang.String * bbb * class java.lang.String * 100 * class java.lang.Integer */ } }

其他方法请参考Java jdk,本文参考自Java jdk1.8

转载地址:http://bcbnl.baihongyu.com/

你可能感兴趣的文章
shell(3)应用
查看>>
OpenResty + Lua 访问Redis
查看>>
11.2 Apache虚拟主机
查看>>
移动APP及游戏推广,有预算为什么还起不了量
查看>>
中国六个漂亮的古镇风景名胜区网站欣赏
查看>>
javascript 基础4
查看>>
计算label的高度:boundingRectWithSize的使用
查看>>
我的友情链接
查看>>
shell脚本
查看>>
HTML5应用与原生应用之间的差异
查看>>
写更好的代码,还是写更少的代码?
查看>>
行如风 Angular 初识5
查看>>
[硕.Love Python] FibonacciHeap(F堆 & 斐波那契堆)
查看>>
java.lang.NoClassDefFoundError: net/tsz/afinal/htt
查看>>
我的友情链接
查看>>
SpringBoot入门之缓存
查看>>
创新=深刻的底层认识+丰富的想象力
查看>>
linux上安装Oracle 11g R2 标准版 64位
查看>>
Windows开关机、远程命令
查看>>
思科命令学习之第二篇
查看>>