Java在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。java
[TOC]數組
反射機制的相關類ide
與Java反射相關的類以下:this
類名 | 用途 |
Class類 | 表明類的實體,在運行的Java應用程序中表示類和接口 |
Field類 | 表明類的成員變量(成員變量也稱爲類的屬性) |
Method類 | 表明類的方法 |
Constructor類 | 表明類的構造方法 |
Class表明類的實體,在運行的Java應用程序中表示類和接口。在這個類中提供了不少有用的方法,這裏對他們簡單的分類介紹。代理
方法 | 用途 | |
asSubclass(Class<U> clazz) | 把傳遞的類的對象轉換成表明其子類的對象 | |
Cast | 把對象轉換成表明類或是接口的對象 | |
getClassLoader() | 得到類的加載器 | |
getClasses() | 返回一個數組,數組中包含該類中全部公共類和接口類的對象 | |
getDeclaredClasses() | 返回一個數組,數組中包含該類中全部類和接口類的對象 | |
forName(String className) | 根據類名返回類的對象 | |
getName() | 得到類的完整路徑名字 | |
newInstance() | 建立類的實例 | |
getPackage() | 得到類的包 | |
getSimpleName() | 得到類的名字 | |
getSuperclass() | 得到當前類繼承的父類的名字 | |
getInterfaces() | 得到當前類實現的類或是接口 |
方法 | 用途 |
getField(String name) | 得到某個公有的屬性對象 |
getFields() | 得到全部公有的屬性對象 |
getDeclaredField(String name) | 得到某個屬性對象 |
getDeclaredFields() | 得到全部屬性對象 |
方法 | 用途 |
getAnnotation(Class annotationClass) | 返回該類中與參數類型匹配的公有註解對象 |
getAnnotations() | 返回該類全部的公有註解對象 |
getDeclaredAnnotation(Class annotationClass) | 返回該類中與參數類型匹配的全部註解對象 |
getDeclaredAnnotations() | 返回該類全部的註解對象 |
方法 | 用途 |
getConstructor(Class...<?> parameterTypes) | 得到該類中與參數類型匹配的公有構造方法 |
getConstructors() | 得到該類的全部公有構造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) | 得到該類中與參數類型匹配的構造方法 |
getDeclaredConstructors() | 得到該類全部構造方法 |
方法 | 用途 |
getMethod(String name, Class...<?> parameterTypes) | 得到該類某個公有的方法 |
getMethods() | 得到該類全部公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) | 得到該類某個方法 |
getDeclaredMethods() | 得到該類全部方法 |
方法 | 用途 |
isAnnotation() | 若是是註解類型則返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) | 若是是指定類型註解類型則返回true |
isAnonymousClass() | 若是是匿名類則返回true |
isArray() | 若是是一個數組類則返回true |
isEnum() | 若是是枚舉類則返回true |
isInstance(Object obj) | 若是obj是該類的實例則返回true |
isInterface() | 若是是接口類則返回true |
isLocalClass() | 若是是局部類則返回true |
isMemberClass() | 若是是內部類則返回true |
Field表明類的成員變量(成員變量也稱爲類的屬性)。code
方法 | 用途 | |
equals(Object obj) | 屬性與obj相等則返回true | |
get(Object obj) | 得到obj中對應的屬性值 | |
set(Object obj, Object value) 設置obj中對應屬性值 |
Method表明類的方法。對象
方法 | 用途 | |
invoke(Object obj, Object... args) | 傳遞object對象及參數調用該對象對應的方法 |
Constructor表明類的構造方法。繼承
方法 | 用途 |
newInstance(Object... initargs) | 根據傳遞的參數建立類的對象 |
示例:接口
Person p = new Person(); p.setAge("1"); p.setName("zs"); p.setSex("0"); p.show(); p.display("china");
//Class<T> 這裏可使用泛型 Class clazz = Person.class; Person person = (Person) clazz.newInstance(); person.setSex("1"); ; person.setName("zs2"); person.setAge("2"); person.show(); person.display("Keroar");
使用反射動態的設置get
Person person2 = (Person) clazz.newInstance(); //這種這隻屬性只能是public修飾的 Field field = clazz.getField("name"); field.set(person2, " 我是名字 "); System.out.println(person2); //private 或者 其餘的須要設置訪問權限 Field field1 = clazz.getDeclaredField("sex"); field1.setAccessible(true); field1.set(person2, "我是sex"); System.out.println(person2);
3 經過反射獲取指定類的指定方法屬性
獲取方法 根據方法名 以及 parameterTypes 可變參數類型,沒有參數就不寫了
public Method getMethod(String name, Class<?>... parameterTypes)
1 獲取設置除public修飾的 //調用傳參方法 display Method method = clazz.getMethod("show"); method.invoke(person2); //2 一樣 設置除public 以外的訪問 //public Method getDeclaredMethod(String name, Class<?>... parameterTypes) // method.setAccessible(true); //獲取方法上註解以及方法參數類型 返回類型 方法名 System.out.println("方法名 : " + method.getName()); System.out.println("參數類型 : " + method.getTypeParameters()); System.out.println("返回類型 : " + method.getReturnType()); //System.out.println("返回全部註解 : " + method.getAnnotations()); //System.out.println("返回全部參數註解 : " + method.getParameterAnnotations()); System.out.println("返回方法參數註解 : " + method.getAnnotation(clazz)); //調用方法 //public Object invoke(Object obj, Object... args) obj 調用的對象,args 傳入方法可變參數 //調用傳參方法 display Method methods = clazz.getMethod("display", String.class); methods.invoke(person2, "我是傳入的國籍參數");
每個運行類只加載一次
有了Class 實例才能進行
1 建立對象 2 獲取類中全部的屬性 方法 父類 內部類 構造 異常 等等... 3 調用屬性和方法等 4 反射的應用 : 動態代理
經過調用 getClass , 獲取 Person 類運行時類的calss對象
Class pClass = p.getClass(); System.out.println(pClass);
//1 經過運行類對象調用 getClass 方法 //2 調用自己.class 屬性 Class clazz1 = Person.class; Class clazz2 = String.class; // 3 經過Class 靜態方法獲取 Class<?> aClass = Class.forName("reflection.Person"); System.out.println(aClass); // 4 類的加載器 ClassLoader classLoader = this.getClass().getClassLoader(); Class<?> aClass1 = classLoader.loadClass("reflection.Person"); System.out.println(aClass1);
除了加載類以外類加載器能夠用來幹嗎?
//1 ClassLoader classLoader = aClass.getClassLoader(); // 加載類 // classLoader.loadClass(); //例如讀取jdbc 配置文件 String name = "jdbc.properties"; InputStream resourceAsStream = classLoader.getResourceAsStream(name); Properties properties = new Properties(); properties.load(resourceAsStream); String property = properties.getProperty("key");
package reflection; public class Person { public String name; private String age; private String sex; // 0 男 1 女 public Person(String name, String age, String sex) { this.name = name; this.age = age; this.sex = sex; } public Person(String name) { this.name = name; } public Person(String name, String age) { this.name = name; this.age = age; } public Person(){ } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void show(){ System.out.println(" emmmmmmm "); } public void display(String contry){ System.out.println(" 個人國籍是 " + contry); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age='" + age + '\'' + ", sex='" + sex + '\'' + '}'; } }