🐻调用方法
2021-3-8
| 2023-8-3
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
通过Class实例获取所有Field对象,同样的,可以通过Class实例获取所有Method信息。Class类提供了以下几个方法来获取Method
  • Method getMethod(name, Class...):获取某个publicMethod(包括父类)
  • Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
  • Method[] getMethods():获取所有publicMethod(包括父类)
  • Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
 
一个Method对象包含一个方法的所有信息:
  • getName():返回方法名称,例如:"getScore"
  • getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class
  • getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class}
  • getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。
 

调用方法

当获取到一个Method对象时,就可以对它进行调用。
如果用反射来调用substring方法:
注意到substring()有两个重载方法,我们获取的是String substring(int)这个方法。
Method实例调用invoke就相当于调用该方法,invoke的第一个参数是对象实例,即在哪个实例上调用该方法,后面的可变参数要与方法参数一致,否则将报错。
 

调用静态方法

如果获取到的Method表示一个静态方法,调用静态方法时,由于无需指定实例对象,所以invoke方法传入的第一个参数永远为null。以Integer.parseInt(String)为例:
 
 

调用非public方法

和Field类似,对于非public方法,虽然可以通过Class.getDeclaredMethod()获取该方法实例,但直接对其调用将得到一个IllegalAccessException。为了调用非public方法,通过Method.setAccessible(true)允许其调用:
此外,setAccessible(true)可能会失败。如果JVM运行期存在SecurityManager,那么它会根据规则进行检查,有可能阻止setAccessible(true)。例如,某个SecurityManager可能不允许对javajavax开头的package的类调用setAccessible(true),这样可以保证JVM核心库的安全。
 

多态

考察这样一种情况:一个Person类定义了hello()方法,并且它的子类Student也覆写了hello()方法,那么,从Person.class获取的Method,作用于Student实例时,调用的方法到底是哪个?
打印出的是Student:hello,因此,使用反射调用方法时,仍然遵循多态原则:即总是调用实际类型的覆写方法(如果存在)。上述的反射代码:
实际上相当于:
  • Java
  • 访问字段调用构造方法
    目录