• JAVA基础知识之JVM-——通过反射查看类信息


    Class实例

    当类被加载之后,JVM中就会生成一个Class实例,通过这个实例就可以访问JVM中的这个类。有三种方式可以获取Class对象

    • 使用Class的静态方法forName(完整包名)
    • 调用类自身的class属性
    • 调用类对象的getClass方法。 该方法继承自java.lang.Object,任何对象都有这个方法。

    通常情况下,推荐用第二种方式。因为第二种方式既不需要重建对象,也不需要调用方法,而是直接读取类的属性。

    从Class实例中获取类的信息

    Class类提供了大量方法来获取Class实例所对应的类的信息,下面是一些常用的方法,

    Constructor<T> getConstructor(Class<T>...parameterTypes), 返回类中带参数的构造函数

    Method getMethod(String name, Class<?>...parameterTypes), 返回带参数的指定方法

    Filed getFiled(String name), 返回类中的属性变量

    关于不定形参Class<T>...parameterTypes的解释,

    例如类中有两个同名方法,

    public void info(String name),

    public void info(String name, int age)

    如果用反射的方法,仅仅通过方法名是无法区分开的,因此需要指明形参

    这里的形参用的是Class<T> 类型的,即 java.lang.String 这种,而不是字符串的String类型,

    正如上面第一节所说,使用 类名.class 可以获取这个类在JVM中的Class实例, 所以要使用反射来获取上面两个类的info方法的方式为,

    1 Class<T> clazz = T.class
    2 
    3 clazz.getMethod("info", String.class)
    4 
    5 clazz.getMethod("info", String.class, Integer.class)

    下面例子演示了Class 的大部分方法,如何从Class实例中获取对应类的信息,

     1 package jvmTest;
     2 
     3 import java.lang.annotation.Annotation;
     4 import java.lang.annotation.Retention;
     5 import java.lang.reflect.Constructor;
     6 import java.lang.reflect.Method;
     7 import java.util.Arrays;
     8 
     9 /*
    10 //定义可重复注解
    11 @Repeatable(Annos.class)
    12 @interface Anno {}
    13 @Retention(Value=RetentionPolicy.RUNTIME)
    14 @interface Annos {
    15     Anno[] value();
    16 }
    17 //使用4个注解修饰该类
    18 @SuppressWarnings(value="unchecked")
    19 @Deprecated
    20 //使用重复注解修饰该类
    21 @Anno
    22 @Anno
    23 */
    24 public class ClassTest {
    25     
    26     private ClassTest() {}
    27     public ClassTest(String name) {
    28         System.out.println("执行有参数构造器");
    29     }
    30     public void info() {
    31         System.out.println("执行无参info");
    32     }
    33     public void info(String str) {
    34         System.out.println("执行有参数info");
    35     }
    36     
    37     class Inner {}
    38     
    39     public static void main(String[] args) throws Exception{
    40         //获取ClassTest在JVM中对应的Class实例
    41         Class<ClassTest> clazz = ClassTest.class;
    42         //获取clazz对应类的全部构造器
    43         Constructor[] ctors = clazz.getDeclaredConstructors();
    44         System.out.println("ClassTest的全部构造器如下:");
    45         for (Constructor c: ctors) {
    46             System.out.println(c);
    47         }
    48         //获取所有public构造器
    49         Constructor[] publicCtors = clazz.getConstructors();
    50         System.out.println("ClassTest的全部public构造器如下:");
    51         for (Constructor c: publicCtors) {
    52             System.out.println(c);
    53         }
    54         //获取所有public方法
    55         Method[] mtds = clazz.getMethods();
    56         System.out.println("ClassTest所有public方法如下:");
    57         for (Method md : mtds) {
    58             System.out.println(md);
    59         }
    60         //获取指定方法
    61         System.out.println("ClassTest中带一个字符串参数的info方法: " + clazz.getMethod("info", String.class));
    62         //获取全部注解
    63         Annotation[] anns = clazz.getAnnotations();
    64         System.out.println("ClassTest全部注解如下: ");
    65         for (Annotation an :  anns) {
    66             System.out.println(an);
    67         }
    68     //    System.out.println("ClassTest类的@SuppressWarning注解为: " + Arrays.toString(clazz.getAnno))
    69         //获取全部内部类
    70         Class<?>[] inners = clazz.getDeclaredClasses();
    71         System.out.println("ClassTest所有内部类: ");
    72         for (Class<?> c :  inners) {
    73             System.out.println(c);
    74         }
    75         //使用forName()加载内部类
    76         //Class inClazz = Class.forName("ClassTest$Inner");
    77         //通过getDeclaringClass()访问该类所在的外部类
    78         //System.out.println("inClazz对应的外部类: " + inClazz.getDeclaringClass());
    79         System.out.println("ClassTest的包为: " + clazz.getPackage());
    80         System.out.println("ClassTest的父类为: " + clazz.getSuperclass());
    81     }
    82 }
  • 相关阅读:
    React同构直出优化总结
    Kubenertes资源分配之Request和Limit解析
    Node Server零基础——开发环境文件自动重载
    Vue组件开发实践之scopedSlot的传递
    【干货合集】Docker快速入门与进阶
    ES6 中的 Set
    十个书写Node.js REST API的最佳实践(上)
    oozie配置安装与原理
    Livy原理详解
    阿里(蚂蚁金服)招聘
  • 原文地址:https://www.cnblogs.com/fysola/p/6102261.html
Copyright © 2020-2023  润新知