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

结语

有不少框架都使用了反射机制,后面还要继续深刻去了解反射的使用方式。

相关文章
相关标签/搜索