Java|反射之获得继承关系

回顾:

当我们获取到某个Class对象时,实际上就获取到了一个类的类型:

Class cls = String.class; // 获取到String的Class

还可以用实例的getClass()方法获取:

String s = "";
Class cls = s.getClass(); // s是String,因此获取到String的Class

最后一种获取Class的方法是通过Class.forName(""),传入Class的完整类名获取:

Class s = Class.forName("java.lang.String");

三种方式获取的Class实例都是同一个实例,因为JVM对每个加载的Class只创建一个Class实例来表示它的类型

获取父类的Class

有了Class实例,我们还可以获取它的父类的Class

  public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class i = Integer.class;
        Class ispc = i.getSuperclass();
        System.out.println(ispc);
        Class iss2 = ispc.getSuperclass();
        System.out.println(iss2);
        System.out.println(iss2.getSuperclass());
    }

上面代码的输出结果:

class java.lang.Number
class java.lang.Object
null

运行上述代码,可以看到,Integer的父类类型是NumberNumber的父类是ObjectObject的父类是null。除Object外,其他任何非interfaceClass都必定存在一个父类类型。

获取interface

由于一个类可能实现一个或多个接口通过Class我们就可以查询到实现的接口类型。例如,查询Integer实现的接口:

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class integerClass = Integer.class;
        Class[] interfaces = integerClass.getInterfaces();
        for (Class i:interfaces ) {
            System.out.println(i);
        }
    }

输出的结果:

interface java.lang.Comparable
interface java.lang.constant.Constable
interface java.lang.constant.ConstantDesc

运行上述代码可知,Integer实现的接口有:

  • java.lang.Comparable
  • java.lang.constant.Constable
  • java.lang.constant.ConstantDesc

要特别注意:getInterfaces()只返回当前类直接实现的接口类型,并不包括其父类实现的接口类型

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        Class ins =  Integer.class.getSuperclass();
        Class[] interfaces = ins.getInterfaces();
        for (Class i:interfaces ) {
            System.out.println(i);
        }
    }

输出结果:        interface java.io.Serializable

Integer的父类是NumberNumber实现的接口是java.io.Serializable

此外,对所有interfaceClass调用getSuperclass()返回的是null获取接口的父接口要用getInterfaces()

System.out.println(java.io.DataInputStream.class.getSuperclass()); // java.io.FilterInputStream,因为DataInputStream继承自FilterInputStream
System.out.println(java.io.Closeable.class.getSuperclass()); // null,对接口调用getSuperclass()总是返回null,获取接口的父接口要用getInterfaces()

如果一个类没有实现任何interface,那么getInterfaces()返回空数组。

继承关系

当我们判断一个实例是否是某个类型时,正常情况下,使用instanceof操作符:

Object n = Integer.valueOf(123);
boolean isDouble = n instanceof Double; // false
boolean isInteger = n instanceof Integer; // true
boolean isNumber = n instanceof Number; // true
boolean isSerializable = n instanceof java.io.Serializable; // true

如果是两个Class实例,要判断一个向上转型是否成立,可以调用isAssignableFrom()

// Integer i = ?
Integer.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Integer
// Number n = ?
Number.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Number
// Object o = ?
Object.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Object
// Integer i = ?
Integer.class.isAssignableFrom(Number.class); // false,因为Number不能赋值给Integer

小结

通过Class对象可以获取继承关系:

  • Class getSuperclass():获取父类类型;
  • Class[] getInterfaces():获取当前类实现的所有接口。

通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。

你可能感兴趣的:(Java,java,jvm,开发语言)