总结内容源自一下文章
粗浅看java反射机制
反射机制应用实践
谈谈java反射机制
Java Reflection(反射机制)详解
八、获取类的 Method
通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
Class<T>类提供了几个方法获取类的方法。
public Method getMethod(String name, Class<?>... parameterTypes)
public Method[] getMethods()
public Method getDeclaredMethod(Stringname,Class<?> parameterTypes)
public Method[] getDeclaredMethods()
getMethod()返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法;
getMethods()返回一个包含某些 Method 对象的数组,这些对象反映此Class 对象所表 示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那 些的类或接口)的公共 member 方法;
getDeclaredMethod()返回一个 Method 对象,该对象反映此Class对象所表示的类或接口的指定已声明方法;
getDeclaredMethods()返回 Method对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
如果知道要调用方法的具体参数类型,就可以直接通过参数类型来获取指定的方法,下面这个例子中返回方法对象名称是“testPrivateMethod”,他的方法参数是 String 类型:
try {
Method privateMethod = classType.getDeclaredMethod("testPrivateMethod", new Class[]{String.class});
System.out.println(privateMethod);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
方法参数以及返回类型
获取指定方法的方法参数是哪些:
Method method = ... //获取Class对象
Class[] parameterTypes = method.getParameterTypes();
获取指定方法的返回类型:
Method method = ... //获取Class对象
Class returnType = method.getReturnType();
通过 Method 对象调用方法
可以通过如下方式来调用一个方法:
//获取一个方法名为doSomesthing,参数类型为String的方法
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1"); // 静态方法第一个参数直接传递null
传入的 null 参数是要调用方法的对象,如果是一个静态方法调用的话则可以用 null 代替指定对象作为 invoke()的参数,在上面这个例子中,如果 doSomething 不是静态方法的话,你就要传入有效的 MyObject 实例而不是 null。 Method.invoke(Object target, Object … parameters)方法的第二个参数是一个可变参数列表,但是你必须要传入与你要调用方法的形参一一对应的实参。就像上个例子那样,方法需要 String 类型的参数,那我们必须要传入一个字符串。
如果方法为私有方法,则需要先改变访问权限,同时,需要捕获异常:
try {
Method privateMethod = ... //获取method
privateMethod.setAccessible(true);
privateMethod.invoke(null, "meth-reflection"); // 第二个参数为函数需要的参数列表,类型为 Object... args
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
九、父类
通过 Class 对象你可以访问类的父类,如下例:
Class superclass = aClass.getSuperclass();
可以看到 superclass 对象其实就是一个 Class 类的实例,所以可以继续在这个对象上进行反射操作。
十、实现的接口
可以通过如下方式获取指定类所实现的接口集合:
Class aClass = ... //获取Class对象,具体方式可见Class对象小节
Class[] interfaces = aClass.getInterfaces();
由于一个类可以实现多个接口,因此 getInterfaces(); 方法返回一个 Class 数组,在 Java 中接口同样有对应的 Class 对象。 注意:getInterfaces() 方法仅仅只返回当前类所实现的接口。当前类的父类如果实现了接口,这些接口是不会在返回的 Class 集合中的,尽管实际上当前类其实已经实现了父类接口。
Class<?> hashMapClass = HashMap.class;
Class<?> [] interfaces = hashMapClass.getInterfaces();
for (Class<?> interf : interfaces) {
System.out.println(interf);
}
System.out.println();
Class<?> superClass = hashMapClass.getSuperclass();
System.out.println(superClass);
十一、构造器
我们可以通过 Class 对象来获取 Constructor 类的实例:
Class aClass = ...//获取Class对象
Constructor[] constructors = aClass.getConstructors();
返回的 Constructor 数组包含每一个声明为公有的(Public)构造方法。 如果知道要访问的构造方法的方法参数类型,你可以用下面的方法获取指定的构造方法,这例子返回的构造方法的方法参数为 String 类型:
Class aClass = ...//获取Class对象
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
如果没有指定的构造方法能满足匹配的方法参数则会抛出:NoSuchMethodException。
构造方法参数
通过如下方式获取指定构造方法的方法参数信息:
Constructor constructor = ... //获取Constructor对象
Class[] parameterTypes = constructor.getParameterTypes();
利用 Constructor 对象实例化一个类
可以通过如下方法实例化一个类:
Constructor constructor = MyObject.class.getConstructor(String.class);
MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");
constructor.newInstance()方法的方法参数是一个可变参数列表,但是当调用构造方法的时候必须提供精确的参数,即形参与实参必须一一对应。在这个例子中构造方法需要一个 String 类型的参数,那我们在调用 newInstance 方法的时候就必须传入一个 String 类型的参数。
调用类的 Class对象的 newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败.
aClass.newInstance(); //直接调用类的newInstance()