第89節: 中的反射技術 反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就可以創建對象,將對象的動作完成,這就是動態的獲取指定的類)。 配置文件把具體實現的類名稱定義到配置文件中。 反射技術的作用可以提高程式的擴展性。 類 用於創建並返回此對象的一個副本 用於指示其他某個對象是否與這 ...
第89節:
Java
中的反射技術
反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就可以創建對象,將對象的動作完成,這就是動態的獲取指定的類)。
配置文件把具體實現的類名稱定義到配置文件中。
反射技術的作用可以提高程式的擴展性。
Object
類
clone()
用於創建並返回此對象的一個副本
equals(Object obj)
用於指示其他某個對象是否與這個對象“相等”
getClass()
用於返回此Object
的運行時類
hashCode()
用於返回該對象的哈希碼值
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);
結言
好了,歡迎在留言區留言,與大家分享你的經驗和心得。
感謝你學習今天的內容,如果你覺得這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。
作者簡介
達叔,理工男,簡書作者&全棧工程師,感性理性兼備的寫作者,個人獨立開發者,我相信你也可以!閱讀他的文章,會上癮!,幫你成為更好的自己。長按下方二維碼可關註,歡迎分享,置頂尤佳。
感謝!承蒙關照!您真誠的贊賞是我前進的最大動力!