Java反射机制及API使用

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Java反射机制及API使用脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

原文地址

反射简单来说,就是动态加载对象,并对对象进行剖析。在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.Student stuClass1 is com.gyl.Student true stuClass2 is class com.gyl.Student true
在运行期间,一个类,只有一个Class对象产生。三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都选第三种,一个字符串可以传入也可写在配置文件中等多种方法。

反射API

获取构造方法

// 返回指定参数类型 public的构造器。  Constructor<T> getConstructor(类<?>... parameterTypes)   // 返回指定参数类型的构造器(public, protected, private)。 Constructor<T> 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”,并且是类自身声明的函数,包含publicprotectedprivate方法。 public Method  getDeclaredMethod(String name, Class[] parameterTypes)  // 获取全部的类自身声明的函数,包含publicprotectedprivate方法。 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<String> 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

脚本宝典总结

以上是脚本宝典为你收集整理的Java反射机制及API使用全部内容,希望文章能够帮你解决Java反射机制及API使用所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。