一、引言 

  很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象。在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假定我们在编译时已经知道了所有类型。2.反射机制,运行我们在运行时发现和使用类的信息。

二、RTTI

  RTTI(Run-Time Type Infomation),运行时类型信息。可以在运行时识别一个对象的类型。类型信息在运行时通过Class对象表示,Class对象包含与类有关的信息,可以使用Class对象来创建类的实例。

  每个类对应一个Class对象,这个Class对象放在.class文件中,当我们的程序中首次主动使用某类型时,会把该类型所对应的Class对象加载进内存,在这篇文章JVM之类加载器中阐述了哪些情况符合首次主动使用。

  既然RTTI和Class对象有莫大的关系,即有了Class对象,就可以进行很多操作,那么,我们如何获取到Class对象呢?有三种方法1. Class.forName("全限定名");(其中,全限定名为包名+类名)。2. 类字面常量,如String.class,对应String类的Class对象。3.通过getClass()方法获取Class对象,如String str = "abc";str.getClass();。

  通过一个类对应的Class对象后,我们可以做什么?我们可以获取该类的父类、接口、创建该类的对象、该类的构造器、字段、方法等等。总之,威力相当大。

  下面我们通过一个例子来熟悉Class对象的各种用法。

package com.hust.grid.leesf.algorithms;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

interface SuperInterfaceA {
};

interface SuperInterfaceB {
};

class SuperC {
    private String name;

    public SuperC() {

    }

    public SuperC(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

class Sub extends SuperC implements SuperInterfaceA, SuperInterfaceB {
    private String name;
    public Sub() {
        super();
    }

    public Sub(String name) {    
        super(name);
        this.name = name;    
    }
    
    public String getName() {
        return name;
    }
}

public class Main {
    public static Sub makeInstance(Class<?> clazz) {
        Sub sub = null;
        try {
            sub = (Sub) clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

        return sub;
    }

    public static void printBasicInfo(Class<?> clazz) {
        System.out.println("CanonicalName : " + clazz.getCanonicalName());
        System.out.println("Name : " + clazz.getName());
        System.out.println("Simple Name : " + clazz.getSimpleName());
        System.out.println("SuperClass Name : "
                + clazz.getSuperclass().getName());
        Class<?>[] interfaces = clazz.getInterfaces();
        for (Class<?> inter : interfaces) {
            System.out.println("Interface SimpleName : "
                    + inter.getSimpleName());
        }
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> cons : constructors) {
            System.out.println("Constructor Name : " + cons.getName()
                    + " And Parameter Count : " + cons.getParameterCount());
        }
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("Method Name : " + method.getName());
        }
    }

    public static void main(String[] args) {
        //Sub sub = new Sub();
        //Class<?> clazz = sub.getClass();
        Class<?> clazz = Sub.class;
        Sub instance = makeInstance(clazz);
        if (instance != null) {
            System.out.println("make instance successful");
        } else {
            System.out.println("make instance unsuccessful");
        }
        printBasicInfo(clazz);
    }
}
View Code

相关文章:

  • 2021-12-31
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-05-24
  • 2021-08-01
  • 2022-03-02
  • 2021-06-13
  • 2021-04-04
相关资源
相似解决方案