获取运行时类的方法的内部结构
那么首先我们要知道运行时类的方法都有哪些内部结构
@注解
权限修饰符 返回值类型 方法名(参数类型1 形参名 , …) throws 异常
- 所以我们说运行时类的方法都有这几种: 注解类型 , 权限修饰符 , 返回值类型 , 方法名 , 参数类型 , 形参名 , 异常
这里我们通过如下几个方法来获取运行时类的方法的内部结构
-
Annotation [] getAnnotations();
- 获取方法声明的注解(注意方法中声明的注解可能是有多个,这个时候我们返回值的形式就是以数组的形式)
- 注意 : 我们只能获取到生命周期为"运行时保留"的注解
-
int getModifiers();
- 获取方法的权限修饰符
- 注意 : 这个方法的返回值类型为int型,用不同的int值表示了不同的权限修饰符
- 0 为 default , 1 为 public , 2 为 private , 4 为 protected , 8 为 static ,16 为 final , 32 为 synchronized , 64 为 volatile
- 以上的这些常量被定义在了Modifiers类中,如果我们要输出对应的权限修饰符,我们就要通过调用Modifier类中的toString()静态方法,通过这个toString()静态方法我们就可以将我们得到的int型的返回值转换为对应的权限修饰符
-
Class getReturnType();
- 获取方法的返回值类型
- 注意: 这个时候我们获得了一个Class类型的对象,我们可以直接输出,这个时候就会返回这个运行时类对应的类名,我们也可以调用Class类中的getName()方法,就可以得到对应的运行时类的全类名
-
String getName();
- 获取方法名
-
Class [] getParameterTypes();
- 获取方法的形参列表中的参数类型
- 返回值类型为Class [] , 因为我们的方法中的形参列表中可能有多个形参
- 注意: 这个时候我们只是得到了形参列表,并没有得到形参名
-
Class [] getExceptionTypes();
- 获取方法中声明的异常(方法中抛出的异常可能有多个,这个时候我们返回值就是以数组的形式)
这里我们通过一个例子来了解如何获得到运行时类的方法的内部结构
-
这里我们要让程序的输出为一种固定的形式
-
形式如下:
-
@注解类型
权限修饰符 返回值类型 方法名(参数类型1, 参数名 ,…) throws XxxException
-
注意: 这里用到了一个自定义类,先给出自定义类Person
package 反射.获取运行时类的成员;
import 注解.类型注解.MyAnnotation;
public class Person {
public int age;
protected String sex;
String name;
private int tizhong;
public Person(){
}
public Person(int age ,String sex , String name , int tizhong){
this.age = age;
this.sex = sex;
this.name = name;
this.tizhong = tizhong;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", sex='" + sex + '\'' +
", name='" + name + '\'' +
", tizhong=" + tizhong +
'}';
}
public void eat() throws Exception{
System.out.println("人类吃饭");
System.out.println("人类吃饭");
}
@MyAnnotation
public String play(int x , int y , String z){
return z;
}
//注意: 这个注解我们并没有给定生命周期,这个时候这个注解就默认为"class保留"
@注解.自定义注解.MyAnnotation
protected void see(){
}
private void feel(){
}
}
然后这里再给出我们的例子(也就是我们的测试程序):
package 反射.获取运行时类的成员;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Demo3 {
public static void main(String[] args) {
//这里我们先获取到运行时类的所有方法(包括私有方法),但是注意这个时候不包括父类中的方法
Method [] methods = Person.class.getDeclaredMethods();
for(Method m : methods){
//获取方法声明的注解
Annotation[] annotations = m.getAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}
//获取方法的权限修饰符
int x = m.getModifiers();
//这里我们通过调用Modifier类中的toString()静态方法将我们的int类型值转换为了对应表示的权限修饰符的String形式
System.out.print(Modifier.toString(x)+"\t");
//获取方法的返回值类型
Class c = m.getReturnType();
System.out.print(c.getName()+"\t");
//获取方法的形参列表中的形参类型
System.out.print("(");
Class [] clazzes = m.getParameterTypes();
if(!(clazzes == null || clazzes.length == 0)){
for (int i = 0 ; i<clazzes.length ; i++){
if(i == clazzes.length-1){
System.out.print(clazzes[i].getName() + " args"+i);
break;
}
System.out.print(clazzes[i].getName() + " args" + i + ",");
}
}
System.out.print(")");
//获取方法抛出的异常
Class [] classes = m.getExceptionTypes();
if(!(classes == null || classes.length == 0)){
System.out.print("throws ");
for (int i = 0 ; i<classes.length ; i++){
if(i == classes.length-1){
System.out.print(classes[i]);
break;
}
System.out.print(classes[i].getName() + ",");
}
}
System.out.println();
System.out.println();
}
}
}
补充:
对于Class对象,如果我们要进行打印输出,这个时候我们建议手动调用一次getName()方法,当然不调用也可以,但是调用getName()方法之后看起来更好