一.為什么使用反射?反射是什么?
反射可以解決在編譯時無法預(yù)知對象和類是屬于那個類的,要根據(jù)程序運行時的信息才能知道該對象和類的信息的問題。在兩個人協(xié)作開發(fā)時,你只要知道對方的類名就可以進行初步的開發(fā)了。
JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。
二.從案例學(xué)習(xí)如何使用反射
public class Man implements AnimalBaseSkill{
public int sex=-1;
private String name;
private Man(int sex, String name) {
this.sex = sex;
this.name = name;
}
public Man() {
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void eat() {}
private class Clan {
String clanName="default family";
public Clan(String familyName) {
this.clanName = familyName;
}
public Clan() {
}
public String getClanName() {
return clanName;
}
public void setClanName(String clanName) {
this.clanName = clanName;
}
}
}
1.如何通過反射獲取Person對象?
- Class.forName(String clazzName)靜態(tài)方法
- 調(diào)用類的class屬性,Person.class返回的就是Person的class對象(推薦使用)
- 調(diào)用某個對象的getClass()方法
eg.
Class class1 = Class.forName("com.ch.java.reflect.Man");
Class class2 = Man.class;
Class class3 =Man.getClass();
但是只有方法一可以獲取私有內(nèi)部類:
Class class_clan=Class.forName("com.ch.java.reflect.Man$Clan");
獲取Class后,然后通過Class獲取構(gòu)造器,通過newInstance()就可以獲取該對象:
Constructor constructor=class1.getConstructor(null);
Man man= (Man) constructor.newInstance();
但是內(nèi)部類的對象要像下面獲取,原因會在(如何獲取類構(gòu)造器?)講解
Constructor constructor=class_clan.getConstructor(Man.class, String.class);
Object family=constructor.newInstance(man, "123");
2.如何獲取類構(gòu)造器?
- getConstructor(Class...parameterTypes):返回此Class對象對應(yīng)類的帶指定形參的public構(gòu)造器,返回參數(shù):Connstructor
- getConstructors():返回此Class對象對應(yīng)類的所有public構(gòu)造器,返回參數(shù):Constructor[]
- getDeclaredConstructor(Class...parameterTypes):返回此class對象對應(yīng)類的帶指定參數(shù)的構(gòu)造器,與構(gòu)造器的訪問權(quán)限無關(guān),返回參數(shù):Constructor[]
- getDeclaredConstructors():返回此class對象對應(yīng)類的所有構(gòu)造器,與構(gòu)造器的訪問權(quán)限無關(guān),返回參數(shù):Constructor[]
person對象的構(gòu)造器獲取很簡單,但是person內(nèi)部類的family對象的構(gòu)造器如何獲???它的坑點在哪里呢?
for (Constructor constructor1 : class_clan.getDeclaredConstructors()) {
System.out.println(constructor1.toString());
}
打印:
public com.ch.java.reflect.Man$Clan(com.ch.java.reflect.Man,java.lang.String)
public com.ch.java.reflect.Man$Clan(com.ch.java.reflect.Man)
3.獲取類成員方法
- getMethod(String name,Class<?>...parameterTypes):返回此class對象對應(yīng)類的帶指定形參的public方法,返回參數(shù):Method
- Method[] getMethods():返回此class對象所表示的類的所有public方法
- Method getDeclaredMethod(string name,Class<?>...parameterTypes):返回此class對象對應(yīng)類的帶指定形參的方法,與方法訪問權(quán)限無關(guān)
- Method[] getDeclaredMethods():返回此class對象對應(yīng)類的全部方法,與方法的訪問權(quán)限無關(guān)
class_1.getMethods();
class_1.getDeclaredMethods();
for (Method method : methods) {
System.out.print(method.getName()+" "+method.getReturnType()+" ");
int i=0;
for (Class<?> aClass : method.getParameterTypes()) {
i++;
System.out.print("params"+i+" "+aClass.toString()+" ");
}
System.out.print("\n");
}
打?。?getName class java.lang.String
setName void params1 class java.lang.String
color void params1 int
getSex int
setSex void params1 int
Disconnected from the target VM, address: '127.0.0.1:52500', transport: 'socket'wait void
wait void params1 long params2 int
wait void params1 long
equals boolean params1 class java.lang.Object *********toString class java.lang.String
hashCode int
getClass class java.lang.Class
notify void
notifyAll void
4.獲取類成員變量
- Field getField(String name):返回此class對象對應(yīng)類的指定名稱的public成員變量
- getFields():返回此class對象對應(yīng)類的所有public成員變量,返回參數(shù):Field[]
- getDeclaredField(String name):返回此class對象對應(yīng)類的指定名稱的成員變量,與成員變量訪問權(quán)限無關(guān)。返回參數(shù):Field
- getDeclaredFields():返回此class對象對應(yīng)類的全部成員變量,與成員變量的訪問權(quán)限無關(guān),返回參數(shù):Field[]
Field[] fields=class_1.getFields();
Field[] fields=class_1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName()+" "+field.getType());
}
打?。?sex int
age int
5.其他
獲取該類內(nèi)部類
Class<?>[] getDeclaredClasses():返回該class隊形對應(yīng)類里包含的全部內(nèi)部類
獲取該類對象所在的外部類
Class<?> getDeclaringClass():返回該Class對象對應(yīng)類所在的外部類
獲取該類對象對應(yīng)類所實現(xiàn)的接口
Class<?>[] getInterfaces():返回該Class對象對應(yīng)類所實現(xiàn)的全部接口
獲取該類對象對應(yīng)類所繼承的父類
Class<? super T> getSuperclass():返回該Class對象對應(yīng)類的超類的Class對象
獲取該類對象對應(yīng)類的修飾符、所在包、類名等基本信息
int getModifiers():返回此類或接口的所有修飾符,修飾符由public、protected、private、final、static、abstract等對應(yīng)的常量組成,返回的整數(shù)應(yīng)使用Modifier工具類的方法來解碼,才可以獲取真是的修飾符
Package getPackage():獲取該類的包
String getName():以字符串形式返回此CLass對象所表示的類的簡稱
判斷該類是否為接口、枚舉、注解類型
boolean isAnnotation():返回此class對象是否表示一個注解類型
boolean isAnnotationPresent(Class<? extends Annotation>annotationClass):判斷此Class對象是否使用類Annotation修飾
boolean isAnonymousClass():返回此class對象是否是一個匿名類
boolean isArray():返回此class對象是否表示一個數(shù)組類
boolean isEnum():返回此class對象是否表示一個枚舉
boolean isInterface():返回此class對象是否表示一個接口
boolean isInstance(Object obj):判斷obj是否是此class對象的實例,該方法可以完全代替instanceof操作符