Java反射机制

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; //正常玩法2
Class 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会发现这简直是新世界的大门

//如有错误,欢迎指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值