基于《Java编程思想》第四版html
咱们要操做一个类实例对象时,通常都要先知道这个类有哪些方法或者成员变量。反射就是在咱们不知道这个类有哪些方法或成员变量时,使用特定方式获得类的这些信息,再根据特定规则去调用对应的方法操做类实例对象。
这中间有两个未知条件java
类信息是经过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
表名.列名=值
的方式按照这个规则实现一个使用了反射的持久化函数,里面没有具体的类型框架
// 略去了异常处理的代码 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
有不少框架都使用了反射机制,后面还要继续深刻去了解反射的使用方式。