反射之二

总结内容源自一下文章
粗浅看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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,826评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,234评论 19 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,289评论 6 13
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,853评论 0 9
  • 一厢情愿的主题简介:命运的:造物弄人。 梦想和爱情的距离。 我们要好好的为自己活,我们要好好的保护我们爱的人,我们...
    导演张升志阅读 385评论 0 0