Java反射(五) - 获取继承关系

获取继承关系


获取父类的Class

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

public class Main {
    public static void main(String[] args) throws Exception {
       Class i = Integer.class;
       Class n = i.getSuperclass();
       System.out.Println(n);
       Class o = n.getSuperclass();
       System.out.println(o);
       System.out.println(o.getSuperclass());
    }
}

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

获取interface

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

public class Main {
    public static void main(String[] args) throws Exception {
        Class s = Integer.class;
        Class[] is = s.getInterfaces();
        for (Class i : is) {
            System.out.println(i);
        }
    }
}

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

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

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

public class Main {
    public static void main(String[] args) throws Exception {
        Class s = Integer.class.getSuperclass();
        Class[] is = s.getInterfaces();
        for (Class i : is) {
            System.out.println(i);
        }
    }
}

Integer的父类是Number,Number实现的接口是java.io.Serializable。

此外,对所有 interface 的Class 调用 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() 方法可以判断一个向上转型是否可以实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java反射中,可以使用以下两种方式获取继承的字段: 1. 使用Class类的getFields()方法获取当前类及其父类中所有的public字段,返回一个Field类型的数组。这个方法只能获取到public字段。 2. 使用Class类的getDeclaredFields()方法获取当前类中所有的字段,包括private和protected字段,但是不包括父类的字段。如果需要获取父类的字段,可以通过调用父类的Class对象的getDeclaredFields()方法来实现。返回一个Field类型的数组。 下面是一个示例代码,演示如何获取继承的字段: ``` import java.lang.reflect.Field; public class ReflectionDemo { public static void main(String[] args) throws Exception { // 获取子类Class对象 Class<?> childClass = Child.class; // 获取所有public字段,包括父类的字段 Field[] publicFields = childClass.getFields(); for (Field field : publicFields) { System.out.println("public field: " + field.getName()); } // 获取子类声明的所有字段,不包括父类的字段 Field[] declaredFields = childClass.getDeclaredFields(); for (Field field : declaredFields) { System.out.println("declared field: " + field.getName()); } // 获取父类声明的所有字段 Class<?> superClass = childClass.getSuperclass(); Field[] superDeclaredFields = superClass.getDeclaredFields(); for (Field field : superDeclaredFields) { System.out.println("super declared field: " + field.getName()); } } } class Parent { private String parentField; public int publicField; } class Child extends Parent { private String childField; public float publicField2; } ``` 输出结果为: ``` public field: publicField public field: publicField2 declared field: childField declared field: parentField super declared field: parentField ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值