和风细雨

世上本无难事,心以为难,斯乃真难。苟不存一难之见于心,则运用之术自出。

反射Reflection综述

反射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

posted on 2008-02-22 09:19 和风细雨 阅读(209) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: