Java學習點滴——Class和反射

基於《Java編程思想》第四版html

前言

咱們要操做一個類實例對象時,通常都要先知道這個類有哪些方法或者成員變量。反射就是在咱們不知道這個類有哪些方法或成員變量時,使用特定方式獲得類的這些信息,再根據特定規則去調用對應的方法操做類實例對象。
這中間有兩個未知條件java

  • 如何記錄類信息
  • 如何肯定規則

類信息是經過Class記錄的,規則是由程序員定的。程序員

Class

Class是一個記錄類信息的類,每一個類(包括Class)都會有一個Class對象。其實現也很好猜想和理解:編譯器掃描完代碼,就能知道類的具體信息,好比有哪些方法,而後把這些信息保存到Class對象中。
由於Class對象並非程序員本身實例化的,因此必須得有一個肯定的名字,約定就叫作class。咱們能夠經過訪問class對象獲得類的信息。
爲了獲取class對象,有三種方法編程

  • 經過類名.class直接訪問
Class c = Integer.class;
  • 經過Class.forName(類名)函數獲取(可能拋出異常,須要放在try catch中)
Class c = Class.forName("Integer");
  • 經過對象.class獲取
Integer n = new Integer ();
Class c = n.getClass();

不論經過哪一種方式獲取的class對象都是同一個對象,也就是說每一個類全局只有一個class對象。能夠查看文檔知道Class有哪些接口,之後多用用就會熟能生巧了。api

反射

當咱們使用反射時,除了Class對象記錄的信息外,還須要一個規則來約束實現者和使用者。
假定有一個持久化功能的規則以下oracle

  • 建立表時,表名和列名均爲帕斯卡格式
  • 使用者存儲信息時,使用相似表名.列名=值的方式
  • 實現的持久化類須要以表名作爲類名,以列名做爲成員變量名,以set+成員變量名做爲方法名,方法名中的成員變量名爲帕斯卡格式

按照這個規則實現一個使用了反射的持久化函數,裏面沒有具體的類型框架

// 略去了異常處理的代碼
public static void save( String s ) {
    String[] tmp = s.split("\\.");
    String table = tmp[0];
    String column = tmp[1].split("=")[0];
    String value = tmp[1].split("=")[1];

    Class c = Class.forName(table);
    Method m = c.getMethod("set" + column, String.class);
    Object o = c.getConstructor().newInstance();
    m.invoke(o,value);
}

按規則要求實現兩個持久化類函數

class Book{
    private String name;

    public Book(){

    }
    public void setName(String name){
        this.name = name;
        System.out.println("Book name = " + name);
    }
}

class Person{
    private String name;

    public Person(){

    }
    public void setName(String name){
        this.name = name;
        System.out.println("Person name = " + name);
    }
}

使用者無需關注具體類型,就能夠完成存儲功能this

public static void main(String[] args) {
    save("Person.Name=Jack");
    save("Book.Name=Five");
}

後續有新增的持久化類時,只要按照規則實現,也能直接嵌入到這個框架中了。code

結語

有不少框架都使用了反射機制,後面還要繼續深刻去了解反射的使用方式。

相關文章
相關標籤/搜索