第89節:
Java
中的反射技術java
反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就能夠建立對象,將對象的動做完成,這就是動態的獲取指定的類)。web
配置文件把具體實現的類名稱定義到配置文件中。jvm
反射技術的做用能夠提升程序的擴展性。ide
Object
類svg
clone()
用於建立並返回此對象的一個副本函數
equals(Object obj)
用於指示其餘某個對象是否與這個對象「相等」學習
getClass()
用於返回此Object
的運行時類ui
hashCode()
用於返回該對象的哈希碼值this
notify()
用於喚醒在此對象監視器上等待的單個線程線程
notifyAll()
用於喚醒在此對象監視器上等待的單個線程
notifyAll()
用於喚醒在此對象監視器上等待的全部線程
toString()
用於返回該對象的字符串
要獲取某文件中的成員,就要先獲取某文件的對象
public class Person{ private String name; private int age; public Person(){ super(); } public Person(String name, int age){ super(); this.name = name; this.age = age; } } // 定義一個方法獲取對象 public static void getClass(){ Person p = new Person(); Class class = p.getClass(); } public static void getClass(){ String className = "com.dashucoding.Person"; Class cla = Class.forName(className); Object obj = cla.newInstance(); // 獲取建立字節碼對象所表示的類的實例 }
pulic T newInstance() throws InstantiationException, IllegalAccessException 建立此Class對象所表示的類的一個實例,對一個帶有一個空參數列表的new表達式實例化這個類。
獲取構造函數
public static void getConstructorDemo() throws Exception { String className = "com.dashucodiing.Person"; Class cla = Class.forName(className); Constructor cons = cla.getConstructor(String.class, int.class); Object obj = cons.newInstance("dashu",12); }
獲取字段
public static void getFieldDemo() throws Exception { String className = "com.dashucoding.Person"; Class cla = Class.forName(className); String fieldName = "age"; //獲取字段 Field field = cla.getField(fieldName); System.out.printlnn(field); }
getField public Field getField(String name) thows NoSuchFieldException, SecurityException. 返回一個Field對象。 NoSuchFieldException 若是沒有找到帶有指定名的字段會報這個錯 NullPointerException 若是name爲null會報這個錯
獲取方法
public static void getMethodDemo() throws Exception { String className = "com.dashucoding.Person"; class cla = Class.forName(className); String methodName = "show"; Method method = cla.getMethod( methodName, String.class,int.class); Object obj = cla.newInstance(); method.invoke(obj, "dashu",12; }
反射技術是這樣的之前先有類,才new
對象,如今有了它以後,先new
對象,把建立對象的動做作完,接着纔在配置文件中添加哪一個類。
當咱們使用的類不明確時,經過配置文件告訴應用程序便可。
File configFile = new File("tempfile\\dashu.properties"); if(!configFile.exists()){ configFile.createNewFile(); } // 讀取配置文件 FileReader fr = new FileReader(configFile); // 爲了獲取其中的鍵值信息 Properties prop = new Properties(); prop.load(fr); for(int x = 1; x<=prop.size(); x++){ String className = prop.getProperty("dashu"+x); Class cla = Class.forName(className); class.newInstance(); }
類加載的概述:
若是某個類被這個程序使用時,若是這個類沒有被加載到內存中,就會由系統經過加載,鏈接,初始化三個步驟實現這個類並對其進行初始化。
加載是由內存進行class
文件的讀取,簡單來講就是class
文件讀入內存中,接着建立一個Class
對象,任何類被使用的時候,由系統創建一個Class
對象。(class
文件加載到內存中)
鏈接:驗證,準備,解析
驗證內部結構是否正確
準備是否爲類的靜態成員分配內存,並設置默認的初始化值
解析是將類的二進制數據中的符號引用換爲直接引用哦
初始化進行初始化的操做
類加載器的概念
類加載器是把.class
文件加載到內存中,並生成對應的Class
對象。
類加載器的分類有哪些?
Bootstrap ClassLoader
根類加載器
Extension ClassLoader
擴展類加載器
System ClassLoader
系統類加載器
描述其做用:
Bootstrap ClassLoader
根類加載器
路徑 jre/lib/rt.jar文件 核心類的加載
Extension ClassLoader
擴展類加載器
路徑 jre/lib/ext目錄 jar包的加載
System ClassLoader
系統類加載器
jvm啓動時加載來自java命令的class文件
反射
源文件 -> 字節碼 -> 建立對象
Class cla = Class.forName("類名"); // 讀取配置文件
Class cla = Person.class
Person p = new Person(); Class cla = p.getClass();
三種方式:
Class cla = Class.forName("com.dashucoding.Person"); Class cla1 = Person.class; Person p = new Person(); Class cla2 = p.getClass(); System.out.println(cla = cla1); System.out.println(cla2 = cla1);
Class.forName()
讀取配置文件
public class Demo { public static void main(String[] args) throws Exception { Juicer j = new Juicer(); j.run(new Apple()); } class Apple { public void squeeze() { System.out.println(); } } class Juicer { public void run(Apple a) { a.squeeze(); } } } interface Fruit { public void squeeze(); } class Apple implements Fruit { public void squeeze(){ System.out.println(""); } } public static void main(String[] args) throws ClassNotFoundException { Class cla1 = Class.forName("com.dashucodiing.Person"); Class cla2 = Person.class; Person p = new Person(); Class cla3 = p.getClass(); }
經過反射獲取帶參構造方法
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); // Person p = (Person) clazz.newInstance(); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); System.out.println(p); } }
反射獲取成員變量
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); // 獲取 Field f = clazz.getField("name"); f.set(p, "李四"); // Field f = clazz.getDeclaredField("name"); // f.set(p, "李四"); } }
獲取方法
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); //獲取 Method m = clazz.getMethod("say"); m.invoke(p); Method m2 = clazz.getMethod("say",int.class); m.invoke(p,12); } }
泛型
package com.dashucoding.demo public class Demo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); // list.add(1); Class clazz = Class.forName("java.util.ArrayList"); Method m = clazz..getMethod("方法名", Object.class); m.invoke(list,"abc"); System.out.println(list); } }
propertyName
改屬性值
public class Tool { public void setProperty (Object obj, String propertyName, Object value) throws Exception { Class clazz = obj.getClass(); Field f = clazz.getDeclaredField(propertyName); f.setAccessible(true); f.set(obj, value); } }
public static void main(String[] args){ } class Student { private String name; private int age; ... }
反射
public class Demo { public void run() { System.out.println("dashucoding"); } }
// 配置文件 獲取這個名詞並加載這個類 com.dashucoding.test.Demo
public static void main(String[] args){ BufferedReader br = new BufferedReader(new FileReader("xxx.properties")); Class clazz = Class.forName(br.readLine()); Demo demo = (Demo) clazz.newInstance(); demo.run(); }
動態代理
public interface User { public void add(); public void delete(); }
public class UserImp implements User{ @Override public void add() { System.out.println("添加"); } @Override public void delete(){ System.out.println("刪除"); } }
public class Test { public static void main(String[] args){ UserImp ui = new UserImp(); ui.add(); ui.delete(); } }
動態代理,在程序運行中產生對象。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h); invoke(Object proxy, Method nethod, Object[] args);
public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler (Object target) { this.target = target; } @Override public Object invoke(Object proxy,Method method,object[] args) throws Throwable { method.invoke(target,args); return null; } }
MyInvocationHandler m = new MyInvocationHandler(si); Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);
好了,歡迎在留言區留言,與你們分享你的經驗和心得。
感謝你學習今天的內容,若是你以爲這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。
做者簡介
達叔,理工男,簡書做者&全棧工程師,感性理性兼備的寫做者,我的獨立開發者,我相信你也能夠!閱讀他的文章,會上癮!,幫你成爲更好的本身。長按下方二維碼可關注,歡迎分享,置頂尤佳。
感謝!承蒙關照!您真誠的讚揚是我前進的最大動力!