反射(Reflection)可以让Java代码得到一个加载类的属性、方法和构造函数的信息,并在安全限制内使用这些属性、方法和构造函数。通过反射,在运行时动态获取类的信息;可以通过和属性文件配合使用,在运行时确定需要使用的类,而不要把所有的类都加载到程序中。
类类型
There is a class named Class.
在面向对象的世界里,万事万物都是对象。类也是个对象,来自于java.lang.class
。任何一个类都是Class的实例对象,称为类类型(Class Type)。
获取一个类类型的方式( 假定Foo为"com.test.Foo"
类,foo为Foo的一个实例):
通过类的
class
属性Class c = Foo.class;
通过实例对象的
getClass()
方法Class c2 = foo.getClass();
通过包名
Class c3 = Class.forName("com.test.Foo");
通过上面三种方式得到的类类型都是相同的,即c1==c2==c3
。可以通过类类型的newInstance()
方法来实例化对象
Foo foo = (Foo)c.newInstance(); // 相当于new Foo()
可以通过getName()
或者getSimpleName()
获取到类的简化名称或者全名
String name = c.getName(); // "com.test.Foo"
String simpleName = c.getSimpleName(); // "Foo"
获取方法
通过类类型获取方法涉及到了Class
类以及Method
类的API
Class
类的api
获取可访问方法(自身的以及继承来的public方法)
getMethods(): Method[]
获取所有自己定义的方法
getDeclaredMethods(): Method[]
Method
类的api
获取方法返回值类型
getReturnType(): Class
获取方法参数列表
getParameterTypes(): Class[]
获取某一方法
getMethod(String name,Class<?>... parameterTypes): Method
使用该方法
invoke(Object obj,Object... args): Object
获取成员变量
通过类类型获取成员变量信息涉及到Class
和Field
类的API
Class
类的API
获取可访问的变量(自身的以及继承来的public变量)
getFields(): Field[]
获取自己定义的变量
getDeclaredFields():Field[]
Field
类的API
获取变量名
getName(): String
获取变量类类型
getType(): Class
获取构造函数
获取构造函数需要Constructor
和Class
类的API
Class
类的api
获取public类型Constructor
getConstructor(): Constructor
获取所有Constructor
getDeclaredConstructor(): Constructor[]
Constructor
类的api
获取参数类型
getParameterTypes(): Class[]
实例化一个对象
newInstance(): T
一些问题的解决方法
// java代码
Method m = c.getMethod("show", String.class);
Object o = m.invoke(c1, "123");
// 抛出的异常
java.lang.IllegalArgumentException: object is not an instance of declaring class
解决方法
1. 将show方法改为静态.
2. invoke
将c1
实例化。Object o = m.invoke(c1.newInstance(), "123");