反射Reflection綜述
反射Reflection是Java被視為動(dòng)態(tài)語言的一個(gè)關(guān)鍵性質(zhì).這個(gè)機(jī)制允許程序在運(yùn)行時(shí)通過Reflection APIs得到任何一個(gè)已知名稱的類的相關(guān)信息,包括其構(gòu)造方法,父類,實(shí)現(xiàn)的接口,成員變量(field)和成員方法(method)的相關(guān)信息,并可在運(yùn)行時(shí)改變成員變量的值或調(diào)用其方法.反射的高度靈活的特性使得它成為Java語言中最具魔力和活力的部分,它是許多流行框架的實(shí)現(xiàn)基礎(chǔ),如Struts,Spring和Hibernate,本篇將列舉一些反射常見的API:實(shí)現(xiàn)反射機(jī)制的類
在JDK中,主要由以下類來實(shí)現(xiàn)Java反射機(jī)制,這些類都位于java.lang.reflect包中:
Class類:代表一個(gè)類。
Field 類:代表類的成員變量(成員變量也稱為類的屬性)。
Method類:代表類的方法。
Constructor 類:代表類的構(gòu)造方法。
Array類:提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法。
反射的源頭:Class類
Java類繼承體系的是一個(gè)單根體系,所有類的都起源于Object類,其內(nèi)聲明了數(shù)個(gè)應(yīng)該在所有Java class中被改寫的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中g(shù)etClass()返回一個(gè)Class object。當(dāng)一個(gè)class被加載,或當(dāng)加載器(class loader)的defineClass()被JVM調(diào)用,JVM 便自動(dòng)產(chǎn)生一個(gè)Class object。
由于在java.lang.Object 類中定義了getClass()方法,因此對(duì)于任意一個(gè)Java對(duì)象,都可以通過此方法獲得對(duì)象的類型。
Class類對(duì)象代表了Java應(yīng)用程序中的各種類和接口.這些類不是程序代碼生成的,而是在Java虛擬機(jī)(JVM)裝入各種類時(shí)生成的.
Static class forName(String className)
這個(gè)方法返回以className為名字的Class對(duì)象。
Object newInstance()
創(chuàng)建該Class對(duì)象代表的類的一個(gè)實(shí)例,類似調(diào)用一個(gè)無參數(shù)的構(gòu)造函數(shù)。這個(gè)方法要求類必須具有一個(gè)無參構(gòu)造函數(shù),如果沒有時(shí)調(diào)用此方法程序會(huì)拋出一個(gè)java.lang.InstantiationException異常,這也是許多框架要求類具有一個(gè)無參構(gòu)造函數(shù)的根本原因
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();
}
}
}
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對(duì)象代表的類的父類。如果該Class是Object,接口,基本數(shù)據(jù)類型或void,則返回nulll,如果這個(gè)類對(duì)象是數(shù)組,則返回Object類的類對(duì)象
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()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對(duì)象實(shí)現(xiàn)的接口。
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
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)
返回構(gòu)造函數(shù),如果有parameterTypes,返回參數(shù)類型為parameterTypes的構(gòu)造函數(shù),Declared是指類中聲明的所有構(gòu)造函數(shù),如果沒有Declared,則只返回共有構(gòu)造函數(shù)。
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.class, int.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();
}
}
}
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.class, int.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參數(shù),返回名字是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
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參數(shù),返回名字是name,且有parameterTypes參數(shù)列表的方法、Declared指聲明中所有的方法(包括public,private,protected),如果沒有Declared,則只返回公有方法。
Method類有一個(gè)重要方法
Object invoke(Object obj,Object[] arg),
通過它可以進(jìn)行類方法調(diào)用,在后面的例子中會(huì)見到。
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);
}
}
}
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);
}
}
}
調(diào)用類的方法
Method類有一個(gè)重要方法
Object invoke(Object obj,Object[] arg),
Object代表返回值,obj是類實(shí)例, arg是參數(shù)數(shù)組。
這個(gè)方法能調(diào)用實(shí)例的一個(gè)方法。如右:
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();
}
}
}
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對(duì)對(duì)象進(jìn)行設(shè)值取值請(qǐng)見:http://www.aygfsteel.com/sitinspring/archive/2008/01/03/172455.html
通過Method對(duì)對(duì)象進(jìn)行設(shè)值取值請(qǐng)見:
http://www.aygfsteel.com/sitinspring/archive/2008/01/05/172970.html
posted on 2008-02-22 09:19 和風(fēng)細(xì)雨 閱讀(212) 評(píng)論(0) 編輯 收藏