在正常的情況下,必須知道一個類的完整路徑引入後,纔可以按照固定的格式產生實例對象化,但是在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方法