java mset_Java 反射机制(包括组成、结构、示例说明等内容)
第1部分 Java 反射機制介紹
Java 反射機制。通俗來講呢,就是在運行狀態中,我們可以根據“類的部分已經的信息”來還原“類的全部的信息”。這里“類的部分已經的信息”,可以是“類名”或“類的對象”等信息。“類的全部信息”就是指“類的屬性,方法,繼承關系和Annotation注解”等內容。
舉個簡單的例子:假設對于類ReflectionTest.java,我們知道的唯一信息是它的類名是“com.skywang.Reflection”。這時,我們想要知道ReflectionTest.java的其它信息(比如它的構造函數,它的成員變量等等),要怎么辦呢?
這就需要用到“反射”。通過反射,我們可以解析出ReflectionTest.java的完整信息,包括它的構造函數,成員變量,繼承關系等等。
在了解了“java 反射機制”的概念之后,接下來思考一個問題:如何根據類的類名,來獲取類的完整信息呢?
這個過程主要分為兩步:
第1步:根據“類名”來獲取對應類的Class對象。
第2步:通過Class對象的函數接口,來讀取“類的構造函數,成員變量”等信息。
下面,我們根據示例來加深對這個概念的理解。示例如下(Demo1.java):
packagecom.skywang.test;importjava.lang.Class;public classDemo1 {public static voidmain(String[] args) {try{//根據“類名”獲取 對應的Class對象
Class> cls = Class.forName("com.skywang.test.Person");//新建對象。newInstance()會調用類不帶參數的構造函數
Object obj =cls.newInstance();
System.out.println("cls="+cls);
}catch(Exception e) {
e.printStackTrace();
}
}
}classPerson {publicPerson() {
System.out.println("create Person");
}
}
運行結果:
create Person
cls=class com.skywang.test.Person
說明:
(01) Person類的完整包名是"com.skywang.test.Person"。而 Class.forName("com.skywang.test.Person"); 這一句的作用是,就是根據Person的包名來獲取Person的Class對象。
(02) 接著,我們調用Class對象的newInstance()方法,創建Person對象。
現在,我們知道了“java反射機制”的概念以及它的原理。有了這個總體思想之后,接下來,我們可以開始對反射進行深入研究了。
第2部分 Class 詳細說明
1 獲取Class對象的方法
我這里總結了4種常用的“獲取Class對象”的方法:
方法1:Class.forName("類名字符串") (注意:類名字符串必須是全稱,包名+類名)
方法2:類名.class
方法3:實例對象.getClass()
方法4:"類名字符串".getClass()
下面,我們通過示例演示這4種方法。示例如下(Demo2.java):
packagecom.skywang.test;importjava.lang.Class;public classDemo2 {public static voidmain(String[] args) {try{//方法1:Class.forName("類名字符串") (注意:類名字符串必須是全稱,包名+類名)//Class cls1 = Class.forName("com.skywang.test.Person");
Class> cls1 = Class.forName("com.skywang.test.Person");//Class cls1 = Class.forName("com.skywang.test.Person");//方法2:類名.class
Class cls2 = Person.class;//方法3:實例對象.getClass()
Person person = newPerson();
Class cls3=person.getClass();//方法4:"類名字符串".getClass()
String str = "com.skywang.test.Person";
Class cls4=str.getClass();
System.out.printf("cls1=%s, cls2=%s, cls3=%s, cls4=%s\n", cls1, cls2, cls3, cls4);
}catch(Exception e) {
e.printStackTrace();
}
}
}classPerson {publicPerson() {
System.out.println("create Person");
}
}
運行結果:
create Person
cls1=class com.skywang.test.Person, cls2=class com.skywang.test.Person, cls3=class com.skywang.test.Person, cls4=class java.lang.String
2 Class的API說明
Class的全部API如下表:
1 Class的全部API如下表:2 public staticClass forName(String className)3 public static Class forName(String name, booleaninitialize, ClassLoader loader)4 publicConstructor getConstructor(Class[] parameterTypes)5 publicConstructor[] getConstructors()6 publicConstructor getDeclaredConstructor(Class[] parameterTypes)7 publicConstructor[] getDeclaredConstructors()8 publicConstructor getEnclosingConstructor()9 publicMethod getMethod(String name, Class[] parameterTypes)10 publicMethod[] getMethods()11 publicMethod getDeclaredMethod(String name, Class[] parameterTypes)12 publicMethod[] getDeclaredMethods()13 publicMethod getEnclosingMethod()14 publicField getField(String name)15 publicField[] getFields()16 publicField getDeclaredField(String name)17 publicField[] getDeclaredFields()18 publicType[] getGenericInterfaces()19 publicType getGenericSuperclass()20 public AnnotationgetAnnotation(Class annotationClass)21 publicAnnotation[] getAnnotations()22 publicAnnotation[] getDeclaredAnnotations()23 public booleanisAnnotation()24 public booleanisAnnotationPresent(Class annotationClass)25 public booleanisAnonymousClass()26 public booleanisArray()27 public booleanisAssignableFrom(Class cls)28 public booleandesiredAssertionStatus()29 public ClassasSubclass(Class clazz)30 publicClass getSuperclass()31 publicClass getComponentType()32 publicClass getDeclaringClass()33 publicClass getEnclosingClass()34 publicClass[] getClasses()35 publicClass[] getDeclaredClasses()36 publicClass[] getInterfaces()37 public booleanisEnum()38 public booleanisInstance(Object obj)39 public booleanisInterface()40 public booleanisLocalClass()41 public booleanisMemberClass()42 public booleanisPrimitive()43 public booleanisSynthetic()44 publicString getSimpleName()45 publicString getName()46 publicString getCanonicalName()47 publicString toString()48 publicClassLoader getClassLoader()49 publicPackage getPackage()50 public intgetModifiers()51 publicProtectionDomain getProtectionDomain()52 publicURL getResource(String name)53 publicInputStream getResourceAsStream(String name)54 publicObject cast(Object obj)55 publicObject newInstance()56 publicObject[] getSigners()57 publicObject[] getEnumConstants()58 public TypeVariable[] getTypeParameters()
View Code
我們根據類的特性,將Class中的類分為4部分進行說明:構造函數,成員方法,成員變量,類的其它信息(如注解、包名、類名、繼承關系等等)。Class中涉及到Annotation(注解)的相關API,可以點擊查看前一章節關于
2.1 構造函數
“構造函數”相關API
//獲取“參數是parameterTypes”的public的構造函數
publicConstructor getConstructor(Class[] parameterTypes)//獲取全部的public的構造函數
publicConstructor[] getConstructors()//獲取“參數是parameterTypes”的,并且是類自身聲明的構造函數,包含public、protected和private方法。
publicConstructor getDeclaredConstructor(Class[] parameterTypes)//獲取類自身聲明的全部的構造函數,包含public、protected和private方法。
publicConstructor[] getDeclaredConstructors()//如果這個類是“其它類的構造函數中的內部類”,調用getEnclosingConstructor()就是這個類所在的構造函數;若不存在,返回null。
public Constructor getEnclosingConstructor()
接下來,我們通過示例對這些API進行說明。示例代碼(DemoClassContructor.java)如下:
packagecom.skywang.test;importjava.lang.Class;importjava.lang.reflect.Constructor;/*** java Class類的Constructor相關API的測試函數
*
*@authorskywang*/
public classDemoClassContructor {public static voidmain(String[] args) {//getDeclaredConstructor() 的測試函數
testGetDeclaredConstructor() ;//getConstructor() 的測試函數
testGetConstructor() ;//getEnclosingConstructor() 的測試函數
testGetEnclosingConstructor() ;
}/*** getDeclaredConstructor() 的測試函數*/
public static voidtestGetDeclaredConstructor() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,獲取構造函數
Constructor cst1 =cls.getDeclaredConstructor();
Constructor cst2= cls.getDeclaredConstructor(new Class[]{String.class});
Constructor cst3= cls.getDeclaredConstructor(new Class[]{String.class, int.class, Gender.class});//根據構造函數,創建相應的對象
cst1.setAccessible(true); //因為Person中Person()是private的,所以這里要設置為可訪問
Object p1 =cst1.newInstance();
Object p2= cst2.newInstance("Juce");
Object p3= cst3.newInstance("Jody", 34, Gender.MALE);
System.out.printf("%-30s: p1=%s, p2=%s, p3=%s\n","getConstructor()", p1, p2, p3);
}catch(Exception e) {
e.printStackTrace();
}
}/*** getConstructor() 的測試函數*/
public static voidtestGetConstructor() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,獲取構造函數//Constructor cst1 = cls.getConstructor();//拋出異常,因為默認構造函數是private權限。//Constructor cst2 = cls.getConstructor(new Class[]{String.class});//拋出異常,因為該構造函數是protected權限。
Constructor cst3 = cls.getConstructor(new Class[]{String.class, int.class, Gender.class});//根據構造函數,創建相應的對象//Object p1 = cst1.newInstance();//cst1.setAccessible(true);//因為Person中Person()是private的,所以這里要設置為可訪問//Object p1 = cst1.newInstance();//Object p2 = cst2.newInstance("Kim");
Object p3 = cst3.newInstance("Katter", 36, Gender.MALE);
System.out.printf("%-30s: p3=%s\n","getConstructor()", p3);
}catch(Exception e) {
e.printStackTrace();
}
}/*** getEnclosingConstructor() 的測試函數*/
public static voidtestGetEnclosingConstructor() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用Person類中有內部類InnerA的構造函數
Constructor cst = cls.getDeclaredConstructor(new Class[]{String.class, int.class});//根據構造函數,創建相應的對象
Object obj = cst.newInstance("Ammy", 18);
System.out.printf("%-30s: obj=%s\n","getEnclosingConstructor()", obj);
}catch(Exception e) {
e.printStackTrace();
}
}
}//枚舉類型。表示“性別”
enumGender{
MALE, FEMALE
}//人
classPerson {private Gender gender; //性別
private int age; //年齡
private String name; //姓名
privatePerson() {this.name = "unknown";this.age = 0;this.gender =Gender.FEMALE;
System.out.println("call--\"private Person()\"");
}protectedPerson(String name) {this.name =name;this.age = 0;this.gender =Gender.FEMALE;
System.out.println("call--\"protected Person(String name)\"");
}public Person(String name, intage, Gender gender) {this.name =name;this.age =age;this.gender =gender;
System.out.println("call--\"public Person(String name, int age, Gender gender)\"");
}public Person(String name, intage) {this.name =name;this.age =age;this.gender =Gender.FEMALE;//內部類在構造方法中
classInnerA{
}//獲取InnerA的Class對象
Class cls = InnerA.class;//獲取“封閉該內部類(InnerA)”的構造方法
Constructor cst =cls.getEnclosingConstructor();
System.out.println("call--\"public Person(String name, int age)\" cst="+cst);
}
@OverridepublicString toString() {return "("+name+", "+age+", "+gender+")";
}
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
call--"private Person()"
call--"protected Person(String name)"
call--"public Person(String name, int age, Gender gender)"
getConstructor() : p1=(unknown, 0, FEMALE), p2=(Juce, 0, FEMALE), p3=(Jody, 34, MALE)
call--"public Person(String name, int age, Gender gender)"
getConstructor() : p3=(Katter, 36, MALE)
call--"public Person(String name, int age)" cst=public com.skywang.test.Person(java.lang.String,int)
getEnclosingConstructor() : obj=(Ammy, 18, FEMALE)
說明:
(01) 首先,要搞清楚Person類,它是我們自定義的類。專門用來測試這些API的。Person中有一個成員變量gender;它是Gender對象,Gender是一個枚舉類。取值可以是MALE或者FEMALE。
(02) testGetDeclaredConstructor() 是“getDeclaredConstructor() 的測試函數”。getDeclaredConstructor()可以“獲取類中任意的構造函數,包含public、protected和private方法”。
(03) testGetConstructor() 是“getConstructor() 的測試函數”。getConstructor()只能“獲取類中public的構造函數”。
(04) testGetEnclosingConstructor() 是“getEnclosingConstructor() 的測試函數”。關于getEnclosingConstructor()的介紹,官方說法是“如果該 Class 對象表示構造方法中的一個本地或匿名類,則返回 Constructor 對象,它表示底層類的立即封閉構造方法。否則返回 null。” 通俗點來說,就是“如果一個類A的構造函數中定義了一個內部類InnerA,則通過InnerA的Class對象調用getEnclosingConstructor()方法,可以獲取類A的這個構造函數”。
2.2 成員方法
“成員方法”相關API
//獲取“名稱是name,參數是parameterTypes”的public的函數(包括從基類繼承的、從接口實現的所有public函數)
publicMethod getMethod(String name, Class[] parameterTypes)//獲取全部的public的函數(包括從基類繼承的、從接口實現的所有public函數)
publicMethod[] getMethods()//獲取“名稱是name,參數是parameterTypes”,并且是類自身聲明的函數,包含public、protected和private方法。
publicMethod getDeclaredMethod(String name, Class[] parameterTypes)//獲取全部的類自身聲明的函數,包含public、protected和private方法。
publicMethod[] getDeclaredMethods()//如果這個類是“其它類中某個方法的內部類”,調用getEnclosingMethod()就是這個類所在的方法;若不存在,返回null。
public Method getEnclosingMethod()
接下來,我們通過示例對這些API進行說明。示例代碼(DemoClassMethod.java)如下:
packagecom.skywang.test;importjava.lang.Class;importjava.lang.reflect.Method;/*** java Class類的Method相關API的測試函數
*
*@authorskywang*/
public classDemoClassMethod {public static voidmain(String[] args) {//getDeclaredMethod() 的測試函數
testGetDeclaredMethod() ;//getMethod() 的測試函數
testGetMethod() ;//getEnclosingMethod() 的測試函數
testGetEnclosingMethod() ;
}/*** getDeclaredMethod() 的測試函數*/
public static voidtestGetDeclaredMethod() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用類的默認構造函數(不帶參數)
Object person =cls.newInstance();//獲取Person中的方法
Method mSetName = cls.getDeclaredMethod("setName", new Class[]{String.class});
Method mGetName= cls.getDeclaredMethod("getName", newClass[]{});
Method mSetAge= cls.getDeclaredMethod("setAge", new Class[]{int.class});
Method mGetAge= cls.getDeclaredMethod("getAge", newClass[]{});
Method mSetGender= cls.getDeclaredMethod("setGender", new Class[]{Gender.class});
Method mGetGender= cls.getDeclaredMethod("getGender", newClass[]{});//調用獲取的方法
mSetName.invoke(person, new Object[]{"Jimmy"});
mSetAge.invoke(person,new Object[]{30});
mSetGender.setAccessible(true); //因為Person中setGender()是private的,所以這里要設置為可訪問
mSetGender.invoke(person, newObject[]{Gender.MALE});
String name= (String)mGetName.invoke(person, newObject[]{});
Integer age= (Integer)mGetAge.invoke(person, newObject[]{});
mGetGender.setAccessible(true); //因為Person中getGender()是private的,所以這里要設置為可訪問
Gender gender = (Gender)mGetGender.invoke(person, newObject[]{});//打印輸出
System.out.printf("%-30s: person=%s, name=%s, age=%s, gender=%s\n","getDeclaredMethod()", person, name, age, gender);
}catch(Exception e) {
e.printStackTrace();
}
}/*** getMethod() 的測試函數*/
public static voidtestGetMethod() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用類的默認構造函數(不帶參數)
Object person =cls.newInstance();//獲取Person中的方法
Method mSetName = cls.getMethod("setName", new Class[]{String.class});
Method mGetName= cls.getMethod("getName", newClass[]{});//Method mSetAge = cls.getMethod("setAge", new Class[]{int.class});//拋出異常,因為setAge()是protected權限。//Method mGetAge = cls.getMethod("getAge", new Class[]{});//拋出異常,因為getAge()是protected權限。//Method mSetGender = cls.getMethod("setGender", new Class[]{Gender.class});//拋出異常,因為setGender()是private權限。//Method mGetGender = cls.getMethod("getGender", new Class[]{});//拋出異常,因為getGender()是private權限。//調用獲取的方法
mSetName.invoke(person, new Object[]{"Phobe"});//mSetAge.invoke(person, new Object[]{38});//mSetGender.invoke(person, new Object[]{Gender.FEMALE});
String name = (String)mGetName.invoke(person, newObject[]{});//Integer age = (Integer)mGetAge.invoke(person, new Object[]{});//Gender gender = (Gender)mGetGender.invoke(person, new Object[]{});//打印輸出
System.out.printf("%-30s: person=%s\n","getMethod()", person);
}catch(Exception e) {
e.printStackTrace();
}
}/*** getEnclosingMethod() 的測試函數*/
public static voidtestGetEnclosingMethod() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用類的默認構造函數(不帶參數)
Object person =cls.newInstance();//根據class,調用Person類中有內部類InnerB的函數
Method mGetInner = cls.getDeclaredMethod("getInner", newClass[]{});//根據構造函數,創建相應的對象
mGetInner.invoke(person, newObject[]{});
System.out.printf("%-30s: person=%s\n","getEnclosingMethod", person);
}catch(Exception e) {
e.printStackTrace();
}
}
}enumGender{
MALE, FEMALE
}classPerson {private Gender gender; //性別
private int age; //年齡
private String name; //姓名
publicPerson() {this("unknown", 0, Gender.FEMALE);
}public Person(String name, intage, Gender gender) {this.name =name;this.age =age;this.gender =gender;
}//獲取”姓名“。權限是 public
publicString getName() {returnname;
}//設置”姓名“。權限是 public
public voidsetName(String name) {this.name =name;
}//獲取”年齡“。權限是 protected
protected intgetAge() {returnage;
}//設置”年齡“。權限是 protected
protected void setAge(intage) {this.age =age;
}//獲取“性別”。權限是 private
privateGender getGender() {returngender;
}//設置“性別”。權限是 private
private voidsetGender(Gender gender) {this.gender =gender;
}//getInner() 中有內部類InnerB,用來測試getEnclosingMethod()
public voidgetInner() {//內部類
classInnerB{
}//獲取InnerB的Class對象
Class cls = InnerB.class;//獲取“封閉該內部類(InnerB)”的構造方法
Method cst =cls.getEnclosingMethod();
System.out.println("call--\"getInner()\" cst="+cst);
}
@OverridepublicString toString() {return "("+name+", "+age+", "+gender+")";
}
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
getDeclaredMethod() : person=(Jimmy, 30, MALE), name=Jimmy, age=30, gender=MALE
getMethod() : person=(Phobe, 0, FEMALE)
call--"getInner()" cst=public void com.skywang.test.Person.getInner()
getEnclosingMethod : person=(unknown, 0, FEMALE)
2.3 成員變量
“成員變量”的相關API
//獲取“名稱是name”的public的成員變量(包括從基類繼承的、從接口實現的所有public成員變量)
publicField getField(String name)//獲取全部的public成員變量(包括從基類繼承的、從接口實現的所有public成員變量)
publicField[] getFields()//獲取“名稱是name”,并且是類自身聲明的成員變量,包含public、protected和private成員變量。
publicField getDeclaredField(String name)//獲取全部的類自身聲明的成員變量,包含public、protected和private成員變量。
public Field[] getDeclaredFields()
接下來,我們通過示例對這些API進行說明。示例代碼(DemoClassField.java)如下:
packagecom.skywang.test;importjava.lang.Class;importjava.lang.reflect.Field;/*** java Class類的"成員變量"相關API的測試函數
*
*@authorskywang*/
public classDemoClassField {public static voidmain(String[] args) {//getDeclaredField() 的測試函數
testGetDeclaredField() ;//getField() 的測試函數
testGetField() ;
}/*** getDeclaredField() 的測試函數
* getDeclaredField() 用于獲取的是類自身聲明的所有成員遍歷,包含public、protected和private方法。*/
public static voidtestGetDeclaredField() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用類的默認構造函數(不帶參數)
Object person =cls.newInstance();//根據class,獲取Filed
Field fName = cls.getDeclaredField("name");
Field fAge= cls.getDeclaredField("age");
Field fGender= cls.getDeclaredField("gender");//根據構造函數,創建相應的對象
fName.set(person, "Hamier");
fAge.set(person,31);
fGender.setAccessible(true); //因為"flag"是private權限,所以要設置訪問權限為true;否則,會拋出異常。
fGender.set(person, Gender.FEMALE);
System.out.printf("%-30s: person=%s\n","getDeclaredField()", person);
}catch(Exception e) {
e.printStackTrace();
}
}/*** getField() 的測試函數
* getField() 用于獲取的是public的“成員”*/
public static voidtestGetField() {try{//獲取Person類的Class
Class> cls = Class.forName("com.skywang.test.Person");//根據class,調用類的默認構造函數(不帶參數)
Object person =cls.newInstance();//根據class,獲取Filed
Field fName = cls.getField("name");
Field fAge= cls.getDeclaredField("age"); //拋出異常,因為Person中age是protected權限。
Field fGender = cls.getDeclaredField("gender"); //拋出異常,因為Person中gender是private權限。//根據構造函數,創建相應的對象
fName.set(person, "Grace");//fAge.set(person, 26);//fGender.set(person, Gender.FEMALE);
System.out.printf("%-30s: person=%s\n","getField()", person);
}catch(Exception e) {
e.printStackTrace();
}
}
}//枚舉類型。表示“性別”
enumGender{
MALE, FEMALE
}//人
classPerson {//private。性別
privateGender gender;//protected。 年齡
protected intage;//public。 姓名
publicString name;publicPerson() {this("unknown", 0, Gender.FEMALE);
}public Person(String name, intage, Gender gender) {this.name =name;this.age =age;this.gender =gender;
}
@OverridepublicString toString() {return "("+name+", "+age+", "+gender+")";
}
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
getDeclaredField() : person=(Hamier, 31, FEMALE)
getField() : person=(Grace, 0, FEMALE)
2.4?類的其它信息
2.4.1 “注解”相關的API
//獲取類的"annotationClass"類型的注解 (包括從基類繼承的、從接口實現的所有public成員變量)
public AnnotationgetAnnotation(Class annotationClass)//獲取類的全部注解 (包括從基類繼承的、從接口實現的所有public成員變量)
publicAnnotation[] getAnnotations()//獲取類自身聲明的全部注解 (包含public、protected和private成員變量)
public Annotation[] getDeclaredAnnotations()
接下來,我們通過示例對這些API進行說明。示例代碼(DemoClassAnnotation.java)如下:
packagecom.skywang.test;importjava.lang.Class;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;/*** java Class類getAnnotation()的測試程序*/
public classDemoClassAnnotation {public static voidmain(String[] args) {try{//根據“類名”獲取 對應的Class對象
Class> cls = Class.forName("com.skywang.test.Person");//獲取“Person類”的注解
MyAnnotation myann = cls.getAnnotation(MyAnnotation.class);
System.out.println("myann="+myann);
}catch(Exception e) {
e.printStackTrace();
}
}
}/*** MyAnnotation是自定義個一個Annotation*/@Retention(RetentionPolicy.RUNTIME)
@interfaceMyAnnotation {
}/*** MyAnnotation 是Person的注解。*/@MyAnnotationclassPerson {
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
myann=@com.skywang.test.MyAnnotation()
說明:
(01) MyAnnotation 是我們自定義個一個Annotation注解。若讀者不明白“注解”,可以參考博文“”TODO
(02) getAnnotation()就是獲取這個類的注解。
2.4.2 “父類”和“接口”相關的API
//獲取實現的全部接口
publicType[] getGenericInterfaces()//獲取父類
public Type getGenericSuperclass()
示例代碼(DemoClassInterface.java)如下:
packagecom.skywang.test;importjava.io.Serializable;importjava.lang.Runnable;importjava.lang.Thread;importjava.lang.Class;importjava.lang.reflect.Type;/*** java Class類的有關父類和接口的測試*/
public classDemoClassInterface {public static voidmain(String[] args) {try{//根據“類名”獲取 對應的Class對象
Class> cls = Class.forName("com.skywang.test.Person");//獲取“Person”的父類
Type father =cls.getGenericSuperclass();//獲取“Person”實現的全部接口
Type[] intfs =cls.getGenericInterfaces();
System.out.println("father="+father);for(Type t:intfs)
System.out.println("t="+t);
}catch(Exception e) {
e.printStackTrace();
}
}
}/*** Person 繼承于 Object,并且實現了Serializable和Runnable接口*/
class Person extends Object implementsSerializable, Runnable{
@Overridepublic voidrun() {
}
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
father=class java.lang.Object
t=interface java.io.Serializable
t=interface java.lang.Runnable
2.4.3 剩余的API
//獲取“類名”
publicString getSimpleName()//獲取“完整類名”
publicString getName()//類是不是“枚舉類”
public booleanisEnum()//obj是不是類的對象
public booleanisInstance(Object obj)//類是不是“接口”
public booleanisInterface()//類是不是“本地類”。本地類,就是定義在方法內部的類。
public booleanisLocalClass()//類是不是“成員類”。成員類,是內部類的一種,但是它不是“內部類”或“匿名類”。
public booleanisMemberClass()//類是不是“基本類型”。 基本類型,包括void和boolean、byte、char、short、int、long、float 和 double這幾種類型。
public booleanisPrimitive()//類是不是“復合類”。 JVM中才會產生復合類,在java應用程序中不存在“復合類”!
public boolean isSynthetic()
示例代碼(DemoClassOtherAPIs.java)如下:
packagecom.skywang.test;importjava.lang.Class;importjava.lang.Runnable;importjava.lang.annotation.ElementType;importjava.util.TreeMap;/*** java Class類的getName(), isInterface()等測試程序
*
*@authorskywang*/
public classDemoClassOtherAPIs {public static voidmain(String[] args) {
Class cls= DemoClassOtherAPIs.class;//獲取“類名”
System.out.printf("%-50s:getSimpleName()=%s\n", cls, cls.getSimpleName());//獲取“完整類名”
System.out.printf("%-50s:getName()=%s\n", cls, cls.getName());//測試其它的API
testOtherAPIs() ;
}public static voidtestOtherAPIs() {//本地類
classLocalA {
}//測試枚舉類型。ElementType是一個枚舉類
Class elementtypeCls = ElementType.class;
System.out.printf("%-50s:isEnum()=%s\n",
elementtypeCls, elementtypeCls.isEnum());//判斷是不是類的對象
Class demoCls = DemoClassOtherAPIs.class;
DemoClassOtherAPIs demoObj= newDemoClassOtherAPIs();
System.out.printf("%-50s:isInstance(obj)=%s\n",
demoCls, demoCls.isInstance(demoObj));//類是不是“接口”
Class runCls = Runnable.class;
System.out.printf("%-50s:isInterface()=%s\n",
runCls, runCls.isInterface());//類是不是“本地類”。本地類,就是定義在方法內部的類。
Class localCls = LocalA.class;
System.out.printf("%-50s:isLocalClass()=%s\n",
localCls, localCls.isLocalClass());//類是不是“成員類”。成員類,是內部類的一種,但是它不是“內部類”或“匿名類”。
Class memCls = MemberB.class;
System.out.printf("%-50s:isMemberClass()=%s\n",
memCls, memCls.isMemberClass());//類是不是“基本類型”。 基本類型,包括void和boolean、byte、char、short、int、long、float 和 double這幾種類型。
Class primCls = int.class;
System.out.printf("%-50s:isPrimitive()=%s\n",
primCls, primCls.isPrimitive());//類是不是“復合類”。 JVM中才會產生復合類,在java應用程序中不存在“復合類”!
Class synCls = DemoClassOtherAPIs.class;
System.out.printf("%-50s:isSynthetic()=%s\n",
synCls, synCls.isSynthetic());
}//內部成員類
classMemberB {
}
}
注意:若程序無法運行,請檢查“forName()”中的包名是否正確!forName()的參數必須是,Person類的完整包名。
運行結果:
class com.skywang.test.DemoClassOtherAPIs :getSimpleName()=DemoClassOtherAPIs
class com.skywang.test.DemoClassOtherAPIs :getName()=com.skywang.test.DemoClassOtherAPIs
class java.lang.annotation.ElementType :isEnum()=true
class com.skywang.test.DemoClassOtherAPIs :isInstance(obj)=true
interface java.lang.Runnable :isInterface()=true
class com.skywang.test.DemoClassOtherAPIs$1LocalA :isLocalClass()=true
class com.skywang.test.DemoClassOtherAPIs$MemberB :isMemberClass()=true
int :isPrimitive()=true
class com.skywang.test.DemoClassOtherAPIs :isSynthetic()=false
說明:isSynthetic()是用來判斷Class是不是“復合類”。這在java應用程序中只會返回false,不會返回true。因為,JVM中才會產生復合類,在java應用程序中不存在“復合類”!
更多內容,點擊
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java mset_Java 反射机制(包括组成、结构、示例说明等内容)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 各版本Anaconda的下载、安装和卸载
- 下一篇: c#窗体程序 内嵌浏览器