反射的基本使用:这里我们写一个简单类,模拟常见的功能。
Java代码
- public class Test {
- // 构造方法
- public Test() {
- System.out.println("无参数构造");
- }
- public Test(String str) {
- System.out.println("有参构造:"+str);
- }
- public void test(){
- System.out.println("普通测试方法:");
- }
- public static void staticTest(){
- System.out.println("静态测试方法");
- }
- // 基本属性
- private Integer number;
- public String name = "张三";
- }
public class Test {// 构造方法public Test() {System.out.println("无参数构造");}public Test(String str) {System.out.println("有参构造:"+str);}public void test(){System.out.println("普通测试方法:");}public static void staticTest(){System.out.println("静态测试方法");}// 基本属性private Integer number;public String name = "张三"; }
1.类加载:
Java代码
- public static void main(String[] args) throws Exception {
- Class<?> c = Class.forName("com.Test");
- // 这里加载类,会调toString 方法, 打印类型,和getName 方法
- // 同时发现类已经存在,说明加载成功
- // 这里常常我们用来动态加载一个类,比如再获得JDBC 连接的时候,
- // 我们可以动态的获得不通厂商的连接:Class.forName("xxx.oracle/mysql")
- System.out.println("类信息:"+c);
- // 同时这里可以直接这只加载器实现:Class.forName(name, initialize, loader)
- }
public static void main(String[] args) throws Exception {Class<?> c = Class.forName("com.Test");// 这里加载类,会调toString 方法, 打印类型,和getName 方法// 同时发现类已经存在,说明加载成功// 这里常常我们用来动态加载一个类,比如再获得JDBC 连接的时候,// 我们可以动态的获得不通厂商的连接:Class.forName("xxx.oracle/mysql")System.out.println("类信息:"+c);// 同时这里可以直接这只加载器实现:Class.forName(name, initialize, loader) }
2 获得方法并且调用:
Java代码
- public static void main(String[] args) throws Exception {
- Class<?> c = Class.forName("com.Test");
- // 这个是获得指定方法,我们先获得普通方法
- Method m = c.getMethod("test");
- // 这里执行会失败了,因为我们们的类没进行实例化
- // m.invoke(c);
- // 这样就不会,这里使用了默认的构造
- m.invoke(c.newInstance());
- // 但是静态方法不用实例化就可以
- Method m2 = c.getMethod("staticTest");
- m2.invoke(c);
- // 当然我们还能获得所有的方法信息
- // 获得该类所有方法
- c.getDeclaredMethods();
- // 获得包括继承的类的所有方法
- c.getMethods();
- }
public static void main(String[] args) throws Exception {Class<?> c = Class.forName("com.Test");// 这个是获得指定方法,我们先获得普通方法Method m = c.getMethod("test");// 这里执行会失败了,因为我们们的类没进行实例化// m.invoke(c);// 这样就不会,这里使用了默认的构造m.invoke(c.newInstance());// 但是静态方法不用实例化就可以Method m2 = c.getMethod("staticTest");m2.invoke(c);// 当然我们还能获得所有的方法信息// 获得该类所有方法c.getDeclaredMethods();// 获得包括继承的类的所有方法c.getMethods();}
3.获得字段信息:
Java代码
- public static void main(String[] args) throws Exception {
- Class<?> c = Class.forName("com.Test");
- // 私有字段是无法通过公有方式访问
- // Field f1 = c.getField("number");
- // public 字段是可以直接访问
- Field f = c.getField("name");
- System.out.println(f);
-
-
- // 这是赋值,必须先获得对象实例,可以为字段赋值
- Object o = c.newInstance();
- f.set(o, "2");
- System.out.println(f.get(o));
- // 其他方法,和获取method 差不多
- }
public static void main(String[] args) throws Exception {Class<?> c = Class.forName("com.Test");// 私有字段是无法通过公有方式访问// Field f1 = c.getField("number");// public 字段是可以直接访问Field f = c.getField("name");System.out.println(f);// 这是赋值,必须先获得对象实例,可以为字段赋值Object o = c.newInstance();f.set(o, "2");System.out.println(f.get(o));// 其他方法,和获取method 差不多}
关于构造器,权限等这些就可以看API,这里仅仅介绍。
4.其他应用:
反射运用得很多,比如我们熟悉的hibernate、spring、以及其他的orm 框架都需要用到。
这里我们模拟hibernate 的实现,来完成对象的保存操作。
// 这是我们模拟的实体bean
Java代码
- // 这是我们模拟的实体bean
- public class Bean {
- private Integer id;
- private String name;
- private String password;
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- }
// 这是我们模拟的实体beanpublic class Bean { private Integer id; private String name; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
|
|