(20120805)java反射

在正常的情況下,必須知道一個類的完整路徑引入後,纔可以按照固定的格式產生實例對象化,但是在java中,也可以通過一個實例化對象找到一個類的完整信息,那麼這就是Class類的功能、
所謂反射程序的運行結果看來也很好理解,既可以通過對象反射求出類的名稱。
正常方式:引入需要的包.類的名稱   通過new實例化 取得實例化對象
反射方式:實例化對象-getClass()方法--得到完整的包.類的名稱
所有的類的對象實際上都是Class類的實例
實例化對象實例:
public class one {
public static void main(String[] args) {
Class<?> c1=null;
Class<?> c2=null;
Class<?> c3=null;
try {
c1=Class.forName("x");
} catch (Exception e) {
e.printStackTrace();
}
c2=new x().getClass();
c3=x.class;
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
}
}
class x{
}
以上三種Class對象方式是一樣的,但是使用forName()的靜態方法實例化Class對象是較爲常見的一種方法。
Class類的 使用
通過無參構造實例化對象可以使用newInstance()方法,但必須保證被實例化的對象存在一個無參的構造方法。
package com.wsl.prictise;
public class instance {
public static void main(String[] args) {
Class<?> c1=null;
try {
c1=Class.forName("com.wsl.prictise.Person");
} catch (Exception e) {
e.printStackTrace();
}
Person p1=null;
try {
p1=(Person)c1.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
p1.setAge(45);
p1.setName("王明");
System.out.print(p1.toString());
}
}
在java開發中,反射是最爲重要的操作原理。

調用有參的構造方法

只是在操作時需要明確的調用類中的構造方法,並將參數傳遞進去以後可以進行實例化操作。操作步驟如下:

(1)通過Class類中的getCostructors()取得本類中的全部構造方法。

(2)向構造方法中傳遞一個對象數組進去,裏面包含了構造方法中所需要的各個參數。


package com.wsl.prictise;


import java.lang.reflect.Constructor;

public class Instancedemo {

public static void main(String[] args) {

Class<?> c1=null;

try {

c1=Class.forName("com.wsl.prictise.Person");

} catch (Exception e) {

e.printStackTrace();

}

Person p1=null;

Constructor<?> cons[]=null;

cons=c1.getConstructors();

try {

p1=(Person)cons[0].newInstance("理性化",20);

} catch (Exception e) {

e.printStackTrace();
}
System.out.print(p1);
}
}
3.取得類的結構

使用到java.lang.reflect包中的以下幾個類:

Constructor:表示類中的構造方法

Field:表示類中的屬性

Method:表示類中的方法、

這三個類都是AccessibleObject類的子類。

取得所實現的全部接口。

package com.wsl.prictise;

interface China{

public static final String NATION="China";

public static final String AUTHOR="王勝利";

public  void saychina();

public String sayHello(String name,int age);

}


public class Person implements China{


private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}


public String  toString() {

return "姓名:"+this.name+"年齡:"+this.age;

}

 

public Person(String name, int age) {

super();

this.name = name;

this.age = age;

}

@Override

public String sayHello(String name, int age) {

return name+",你好,我今年"+age+"歲了!";

}

@Override

public void saychina() {

System.out.println("作者:"+AUTHOR+",國籍:"+NATION);

}

}


package com.wsl.prictise;

import java.lang.reflect.Constructor;

public class Instancedemo {

public static void main(String[] args) {

Class<?> c1=null;

try {

c1=Class.forName("com.wsl.prictise.Person");

} catch (Exception e) {

e.printStackTrace();

}

Class<?> c[]=c1.getInterfaces();

for (int i = 0; i < c.length; i++) {

System.out.print("實現的接口名稱是:"+c[i].getName());

}

}

}

取得父類:

一個類可以實現多個接口,但是隻能繼承一個父類,所有如果要取得一個類的父類,可以直接使用Class類中的getSuperClass()方法

Class<?> c1=null;

try {

c1=Class.forName("com.wsl.prictise.Person");

} catch (Exception e) {

e.printStackTrace();

}

Class<?> c=c1.getSuperclass();

System.out.println(c.getName());


取得全部構造方法:用getConstructors()


4.取得全部方法:

要取得一個類中的全部方法,可以使用class類中的getMethods()方法。此方法返回一個Method類的對象數組。

Class<?> c1=null;

try {

c1=Class.forName("com.wsl.prictise.Person");

} catch (Exception e) {

e.printStackTrace();

}

Method m[]=c1.getMethods();

for (int i = 0; i < m.length; i++) {

Class<?> r=m[i].getReturnType();

Class<?> p[]=m[i].getParameterTypes();

int xx=m[i].getModifiers();

System.out.print(Modifier.toString(xx));

System.out.print(r.getName());

System.out.print(m[i].getName());

System.out.print("(");

for (int j = 0; j < p.length; j++) {

System.out.print(p[j].getName()+""+"arg"+j);

if (j<p.length-1) {

System.out.print(",");

}

}

Class<?> ex[]=m[i].getExceptionTypes();

if (ex.length>0) {

System.out.print(") throws");

}

else {

System.out.print(")");

}

for (int k = 0; k < ex.length; k++) {

System.out.print(ex[k].getName());

if (k<ex.length-1) {

System.out.print(",");
}
}
System.out.println();
}
}
開發工具就是利用反射的原理、

在使用IDE進行程序開發時,基本上都是帶隨筆提示功能的,即使用了一個.就可以找到一個類的全部方法。

5.取得全部屬性

在反射操作中,取得一個類的全部屬性,但是在取屬性時有兩個不同的操作:

(1)得到實現的接口或父類中的公共屬性,

Public Field() getFields[] throws SecutityExecption

(2)得到本類中的全部屬性:

Public Field[] getDeclaredFields() throws SecurityExction

Class<?> c1=null;

try {

c1=Class.forName("com.wsl.prictise.Person");

} catch (Exception e) {

e.printStackTrace();

}
{
Field f[]=c1.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
Class<?> r=f[i].getType();
int no=f[i].getModifiers();
String priv=Modifier.toString(no);
System.out.print("本類屬性");
System.out.print(priv+" ");
System.out.print(r.getName());
System.out.println(f[i].getName());
System.out.println(";");
}
}
}

6.通過反射調用類中的方法

(1)通過Class類的getMethod(String name,class...parameterTypes)方法 取得一個Method的對象,並設置此方法操作時所需要的參數類型

(2)之後可以使用invoke()進行調用,並向方法中傳遞要設置的參數。

範例:
Class<?> c1=null;
try {
c1=Class.forName("com.wsl.prictise.Person");
} catch (Exception e) {

e.printStackTrace();

}
try {
Method mh=c1.getMethod("saychina");

mh.invoke(c1.newInstance());

e.printStackTrace();
}
Class<?> c1=null;
try {
c1=Class.forName("com.wsl.prictise.Person");
} catch (Exception e) {
e.printStackTrace();
}
try {
Method mh=c1.getMethod("saychina");
Method md=c1.getMethod("sayHello", String.class,int.class);
String rv=null;
rv=(String)md.invoke(c1.newInstance(), "王明",23);
mh.invoke(c1.newInstance());
System.out.print(rv);
} catch (Exception e) {
e.printStackTrace();
}
調用setter及getter方法
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章