Java反射机制

来源:互联网 发布:php 开源社区系统 编辑:程序博客网 时间:2024/06/12 00:55

Java反射是在运行状态中,对于任意一个类,都知道这个类的所有属性和方法;对于任意一个对象,都能调用他的任意方法和属性。这种动态获取信息及动态调用对象方法的功能称为Java语言的反射机制。换句话说,Java程序可以加载一个运行时才知道名称的class,获悉其完整构造,并生成其对象实体,或对其fields设值、或唤醒其methods。(摘自360百科)

在讲反射之前,先了解一下如下几个类:
类类(Class类):Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。(摘自JDK API)
方法类(Method类):Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。(摘自JDK API)
属性类(Field类):Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。(摘自JDK API)
构造器类(Constructor类):Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。 Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,但是如果发生收缩转换,则抛出 IllegalArgumentException。(摘自JDK API)
*注意:当一个类被加载且创建对象时,和该类相关的一个类型为Class的对象就会自动创建,任何对象调用getClass()方法都可以获取和该对象相关的一个Class对象。

Class对象经常调用的方法:

    String getName() //返回类的名字    Constructor[] getDeclaredConstructors() //返回类的全部构造方法    Field[] getDeclaredFields() //返回类的全部成员变量    Method[] getDeclaredMethods() //返回类的全部方法

如果说到这里都不太好理解,看看下面它们在代码中的使用方式就好了。

一、反射的作用:
1.通过反射机制发现对象的类型,发现类型的方法、属性、构造函数(在可视化编程的时候获取控件类型用的比较多)
2.可以创建对象并访问任意对象方法和属性
作用1代码示例:

 package ex;     public class Test {       public static void main(String args[])  {           Class cls = "abc".getClass();         System.out.println(cls);     }   } //输出结果: //class java.lang.String

作用2代码示例:

package ex;     import java.util.Scanner; public class Test {       public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException  {           Scanner sc = new Scanner(System.in);         System.out.println("请选择创建的图形:1.圆形   2.三角形");         int choice = sc.nextInt();         Shape figure = new Shape();         if(choice == 1) {             figure = (Shape)Class.forName("ex.Circle").newInstance();             //注:newInstance(): 弱类型。低效率。只能调用无参构造         }         else {             figure = (Shape)Class.forName("ex.Triangle").newInstance();         }         figure.show();         sc.close();     }   } class Shape{     void show() {     } } class Circle extends Shape{     void show() {         System.out.println("这是一个圆");     } }class Triangle extends Shape{    void show() {        System.out.println("这是一个三角形");    }}//输出结果:/*请选择创建的图形:1.圆形   2.三角形 *1 *这是一个圆 */

二、Reflection的简单操作示例
示例1:获得想操作类的java.lang.Class对象
eg:

Class cls = Class.forName("java.lang.String");//正常玩法Class cls = char.class; //正常玩法2Class cls = Integer.TYPE; //基本类型封装类的玩法Class cls = "abc".getClass(); //正常玩法3

示例2:获取想操作类的所有方法列表
eg:

package ex;     //import java.util.Scanner; import java.lang.reflect.*; public class Test {      public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException  {              Class cls = Class.forName("java.lang.String");            Method[] med = cls.getDeclaredMethods();            for(int i = 0;i<5;i++) { //先打印五个函数,太多了                System.out.println(med[i].toString());            }     }   }//输出结果:/*public boolean java.lang.String.equals(java.lang.Object) *public java.lang.String java.lang.String.toString() *public int java.lang.String.hashCode() *public int java.lang.String.compareTo(java.lang.String) *public int java.lang.String.compareTo(java.lang.Object) */

示例3:获取想操作类的构造器信息

package ex;     //import java.util.Scanner; import java.lang.reflect.*; public class Test {       public static void main(String args[]) throws ClassNotFoundException{          Class cls = Class.forName("java.lang.String");        Constructor[] cst = cls.getDeclaredConstructors();        for(int i = 0;i<cst.length;i++) {            System.out.println(cst[i]);        }     }   }//输出结果:/*public java.lang.String(java.lang.String) *public java.lang.String(char[],int,int) *public java.lang.String(byte[],int) *public java.lang.String(byte[],int,int,int)*/

示例4:获得想操作类的字段

package ex;     //import java.util.Scanner; import java.lang.reflect.*; public class Test {       public static void main(String args[]) throws ClassNotFoundException{          Class cls = Class.forName("java.lang.String");        Field[] fed = cls.getFields();        for(int i = 0;i<fed.length;i++) {            System.out.println(fed[i]);        }     }   }//输出结果:/*public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER*/

三、一个简单的例子:找出类的方法
有的时候,程序执行到某处的时候才会知道要调用某个方法,这里我们用反射来实现通过用户输入方法名来调用方法

package ex;     import java.util.Scanner; import java.lang.reflect.*; public class Test {       public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{        System.out.println("What is your favourite color?");        Scanner sc = new Scanner(System.in);        String color = sc.nextLine();        Class cls = Class.forName("ex.fruit");        //Class []para = new Class[2];        Method mtd = cls.getDeclaredMethod(color);//parameterTypes        mtd.invoke(null);        sc.close();     }   } class fruit{     static void red() {         System.out.println("You like red.");     }     static void blue() {         System.out.println("You like blue.");     }     static void black() {         System.out.println("You like black.");     }     static void white() {         System.out.println("You like white.");     } }//运行结果 /*What is your favourite color?  *blue  *You like blue. */

//这里只是为了用反射而用反射,几个例子都不是很好,打开API会发现这简直是新世界的大门

//如有错误,欢迎指正

原创粉丝点击