对于程序员来说,应该很少需要直接使用反射工具;之所以在语言中提供它们,是为了支持其他Java特性,比如对象序列化、Java Beans以及RMI。还有就是在很多框架中,也是应用到了反射机制。
在初学时,只知道这是个生成驱动实例的语句,而这其实就是应用了反射
// Load the driver Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver"); Connection c = DriverManager.getConnection( dbUrl, user, password);主要的四个功能: - 获取对象所属的类 - 获取类的成员变量、方法 - 运行时创建对象 - 运行时调用对象的方法
通过对象获取包名、类名实例.getClass().getName()
package Reflection; class Demo { // your code here } public class Test { ; public static void main(String[] args) { Demo demo = new Demo(); System.out.println(demo.getClass().getName()); } } 获取class类有以下三种方式
package Reflection; class Demo { // your code here } public class Test { ; public static void main(String[] args) { Class<?> demo1 = null; Class<?> demo2; Class<?> demo3; // 1. class.forName("类的路径") try { demo1 = Class.forName("Reflection.Demo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 2. 实例.getClass() demo2 = new Demo().getClass(); // 3. 类名.class demo3 = Demo.class; if (demo1 != null) { System.out.println(demo1.getName()); } System.out.println(demo2.getName()); System.out.println(demo3.getName()); } } 运行时创建对象、调用对象的方法 package Reflection; class Dog { private String name; private String owner; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return this.name + "'s owner is " + this.owner; } } public class Test { ; public static void main(String[] args) { Class<?> demo = null; try { // 使用反射机制加载类Dog demo = Class.forName("Reflection.Dog"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Dog dog = null; // 在运行时动态地创建类Dog的对象 try { dog = (Dog)demo.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // 运行时调用对象的方法 if (dog != null) { dog.setName("qiuqiu"); } if (dog != null) { dog.setOwner("lxb"); } System.out.println(dog); } }还有需要注意一点的是,如果我们没自定义无参构造函数,而是直接定义了有参构造函数,会报以下错误
null java.lang.InstantiationException: Reflection.Dog at java.lang.Class.newInstance(Class.java:427) at Reflection.Test.main(Test.java:49) Caused by: java.lang.NoSuchMethodException: Reflection.Dog.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.newInstance(Class.java:412) ... 1 more Process finished with exit code 0所以在程序运行时创建对象时,我们需要自定义无参构造函数
class Dog { private String name; private String owner; // 自定义的无参构造函数 public Dog() {} // 有参构造函数 public Dog(String name, String owner) { this.name = name; this.owner = owner; } // 省略 } 其它功能可用构建器创建新对象,通过Constructor类取得其它类的构造函数
用get()和set()方法读取和修改与Field对象关联的字段
用invoke()方法调用与Method对象关联的方法,即调用其他类的方法
此外,我们可调用方法getFields(),getMethods(),getConstructors(),分别返回用于表示字段、方法以及构建器的对象数组,取得并修改数组的信息
取得其他类的父类、实现的接口、权限修饰符、属性类型等
