【整理】反射Reflection综述

Junglesong 发表于 2008-04-05 14:59:39

反射Reflection是Java被视为动态语言的一个关键性质.这个机制允许程序在运行时通过Reflection APIs得到任何一个已知名称的类的相关信息,包括其构造方法,父类,实现的接口,成员变量(field)和成员方法(method)的相关信息,并可在运行时改变成员变量的值或调用其方法.反射的高度灵活的特性使得它成为Java语言中最具魔力和活力的部分,它是许多流行框架的实现基础,如Struts,Spring和Hibernate,本篇将列举一些反射常见的API:

实现反射机制的类
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

反射的源头:Class类
Java类继承体系的是一个单根体系,所有类的都起源于Object类,其内声明了数个应该在所有Java class中被改写的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class object。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class object。
由于在java.lang.Object 类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。
Class类对象代表了Java应用程序中的各种类和接口.这些类不是程序代码生成的,而是在Java虚拟机(JVM)装入各种类时生成的.

Static class forName(String className)
这个方法返回以className为名字的Class对象。
Object newInstance()
创建该Class对象代表的类的一个实例,类似调用一个无参数的构造函数。这个方法要求类必须具有一个无参构造函数,如果没有时调用此方法程序会抛出一个java.lang.InstantiationException异常,这也是许多框架要求类具有一个无参构造函数的根本原因
package com.sitinspring;

public class Member{
  
private String name;
  
private int age;
  
private float salary;
  
  
public Member(){
    name
="Unknown";
    age
=20;
    salary
=1.00f;
  }
  
  
public String toString(){
    
return "名称="+name+" 年龄="+age+" 薪水="+salary;
  }
  
  
public static void main(String[] args){
    
try{
      Class cls
=Class.forName("com.sitinspring.Member");
      Member member
=(Member)cls.newInstance();
      System.out.println(member);
    }
    
catch(Exception ex){
      ex.printStackTrace();
    }
  }
}

Class getSuperclass()
返回该Class对象代表的类的父类。如果该Class是Object,接口,基本数据类型或void,则返回nulll,如果这个类对象是数组,则返回Object类的类对象
public class Member extends Thread implements Comparable{
  
private String name;
  
private int age;
  
private float salary;
  
  
public Member(){
    name
="Unknown";
    age
=20;
    salary
=1.00f;
  }
  
  
public String toString(){
    
return "名称="+name+" 年龄="+age+" 薪水="+salary;
  }
  
  
public int compareTo(Object obj){
    Member another
=(Member)obj;
    
    
return this.age-another.age;
  }
  
  
public static void main(String[] args){
    System.out.println(Member.
class.getSuperclass());
    System.out.println(Object.
class.getSuperclass());
    System.out.println(Comparable.
class.getSuperclass());
    System.out.println(
int.class.getSuperclass());
    System.out.println(
void.class.getSuperclass());
    System.out.println(String[].
class.getSuperclass());
  }
}
Class[] getInterfaces()
返回该Class对象实现的接口。
public class Member implements Comparable,Runnable{
  
private String name;
  
private int age;
  
private float salary;
  
  
public Member(){
    name
="Unknown";
    age
=20;
    salary
=1.00f;
  }
  
  
public String toString(){
    
return "名称="+name+" 年龄="+age+" 薪水="+salary;
  }
  
  
public int compareTo(Object obj){
    Member another
=(Member)obj;
    
    
return this.age-another.age;
  }
  
  
public void run(){
    
  }
  
  
public static void main(String[] args){
    
for(Class cls:Member.class.getInterfaces()){
      System.out.println(cls.toString());
    }
  }
}
输出:
interface java.lang.Comparable
interface java.lang.Runnable

Construtor[] getConstructors()
Construtor[] getDeclaredConstructors()
Construtor[] getConstructors(Class[] parameterTypes)
Construtor[] getDeclaredConstructors(Class[] parameterTypes)

返回构造函数,如果有parameterTypes,返回参数类型为parameterTypes的构造函数,Declared是指类中声明的所有构造函数,如果没有Declared,则只返回共有构造函数。
public class Member {
  
private String name;

  
private int age;

  
private float salary;

  
public Member() {
    name 
= "Unknown";
    age 
= 20;
    salary 
= 1.00f;
  }

  
public Member(String name, int age, float salary) {
    
this.name = name;
    
this.age = age;
    
this.salary = salary;
  }

  
public String toString() {
    
return "名称=" + name + " 年龄=" + age + " 薪水=" + salary;
  }

  
public static void main(String[] args) {
    
for (Constructor cls : Member.class.getConstructors()) {
      System.out.println(cls.toString());
    }

    
try {
      Class cls 
= Class.forName("com.sitinspring.Member");
      Constructor con 
=cls.getConstructor(new Class[]{String.classint.class,float.class});
      Member member 
= (Member) con.newInstance(new Object[] {
          
new String("Sitinspring"), new Integer(30),
          
new Float(20000) });
      System.out.println(member); 
    } 
catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Field[] getFields()
Field[] getDeclaredFields()
Field getField(String name)
Field[] getDeclaredFields(String name)

返回成员变量。如果有name参数,返回名字是name的成员变量,Declared指声明中所有的成员变量,如果没有Declared,则只返回公有成员变量。
public class Member {
  
private String name;

  
private int age;

  
private float salary;
  
  
public String field1;
  
protected String field2;

  
public static void main(String[] args) {
    
for (Field field : Member.class.getFields()) {
      System.out.println(field);
    }
    
    
for (Field field : Member.class.getDeclaredFields()) {
      System.out.println(field.getName());
    }
  }
}

输出:
public java.lang.String com.sitinspring.Member.field1
name
age
salary
field1
field2

Method[] getMethods()
Method[] getDeclaredMethods()
Method getMethod(String name,Class[] parameterTypes)
Method[] getDeclaredMethods(String name ,Class[] parameterTypes)

返回类的方法,如果有name和parameterTypes参数,返回名字是name,且有parameterTypes参数列表的方法、Declared指声明中所有的方法(包括public,private,protected),如果没有Declared,则只返回公有方法。

Method类有一个重要方法
Object invoke(Object obj,Object[] arg),
通过它可以进行类方法调用,在后面的例子中会见到。
public class Member {
  
private String name;

  
private int age;

  
private float salary;

  
public Member() {
    name 
= "Unknown";
    age 
= 20;
    salary 
= 1.00f;
  }

  
public String toString() {
    
return "名称=" + name + " 年龄=" + age + " 薪水=" + salary;
  }
  
  
public int getAge() {
    
return age;
  }

  
protected String getName() {
    
return name;
  }

  
private float getSalary() {
    
return salary;
  }
  
  
public static void main(String[] args) {
    
for (Method method : Member.class.getMethods()) {
      System.out.println(method);
    }
    System.out.println(
"--------------");
    
for (Method method : Member.class.getDeclaredMethods()) {
      System.out.println(method);
    }
  }
}

调用类的方法
Method类有一个重要方法
Object invoke(Object obj,Object[] arg),
Object代表返回值,obj是类实例, arg是参数数组。

这个方法能调用实例的一个方法。如右:
public class Caculator{
  
public int add(int op1,int op2){
    
return op1+op2;
  }
  
  
public int substract(int op1,int op2){
    
return op1-op2;
  }
  
  
public static void main(String[] args){
    
try{
      Caculator caculator
=new Caculator();
      
      Method addMethod 
= caculator.getClass().getMethod(
          
"add",
          
new Class[] { int.class,int.class });

      Object result1
=addMethod.invoke(caculator, new Object[] { 1,2 });
      System.out.println(
"和="+result1);
      
      Method substractMethod 
= caculator.getClass().getMethod(
          
"substract",
          
new Class[] { int.class,int.class });
      
      Object result2
=substractMethod.invoke(caculator, new Object[] { 3,4 });
      System.out.println(
"差="+result2);
    }
    
catch(Exception ex){
      ex.printStackTrace();
    }
  }
}

通过Field对对象进行设值取值请见:http://www.blogjava.net/sitinspring/archive/2008/01/03/172455.html

通过Method对对象进行设值取值请见:
http://www.blogjava.net/sitinspring/archive/2008/01/05/172970.html

收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定