第89節:Java中的反射技術

第89節:Java中的反射技術

第89節:Java中的反射技術java

反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就能夠建立對象,將對象的動做完成,這就是動態的獲取指定的類)。web

配置文件把具體實現的類名稱定義到配置文件中。jvm

反射技術的做用能夠提升程序的擴展性。ide

Objectsvg

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);

結言

好了,歡迎在留言區留言,與你們分享你的經驗和心得。

感謝你學習今天的內容,若是你以爲這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。

做者簡介

達叔,理工男,簡書做者&全棧工程師,感性理性兼備的寫做者,我的獨立開發者,我相信你也能夠!閱讀他的文章,會上癮!,幫你成爲更好的本身。長按下方二維碼可關注,歡迎分享,置頂尤佳。

感謝!承蒙關照!您真誠的讚揚是我前進的最大動力!

努力努力再努力Jeskson

相關文章
相關標籤/搜索