共计 2509 个字符,预计需要花费 7 分钟才能阅读完成。
当我们获取到某个 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
:
// reflection
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
实现的接口:
// reflection
import java.lang.reflect.Method;
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()
只返回当前类直接实现的接口类型,并不包括其父类实现的接口类型:
// reflection
import java.lang.reflect.Method;
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()
方法可以判断一个向上转型是否可以实现。