java:isAssignableFrom方法使用及instanceof对比
1 前言
Class类的方法isAssignableFrom,常见于源码中判断父子类关系时使用。X.class.isAssignableFrom(Y.class),表示判断Y是否为X的子类(或Y接口(类)是否继承(实现)了X接口),均适用于类或接口中,且X.class.isAssignableFrom(X.class)仍返回true。
isAssignableFrom为native方法,底层使用C/C++实现。
instanceof为java中判断实例对象是否为某个类的类型的关键字,同常见于框架源码中使用。
2 使用
public class TestIsAssign {
public static void main(String[] args) {
System.out.println(Ad.class.isAssignableFrom(Ad.class));
System.out.println(Ad.class.isAssignableFrom(Cd.class));
System.out.println(AI.class.isAssignableFrom(Cd.class));
System.out.println(Bd.class.isAssignableFrom(Cd.class));
System.out.println(Bd.class.isAssignableFrom(Ad.class));
System.out.println(AI.class.isAssignableFrom(BI.class));
System.out.println(BI.class.isAssignableFrom(BI.class));
System.out.println(Object.class.isAssignableFrom(Ad.class));
System.out.println("-------");
System.out.println(new Cd() instanceof Ad);
System.out.println(null instanceof Ad);
System.out.println(null instanceof Object);
System.out.println((Ad)null instanceof Ad);
System.out.println((Ad)new Cd() instanceof Ad);
}
public void run1(){}
}
class Ad{}
class Bd extends Ad{}
class Cd extends Bd implements AI{}
interface BI extends AI{}
interface AI{}
执行结果如下:
true
true
true
true
false
true
true
true
-------
true
false
false
false
true
上述比对可知,isAssignableFrom用于表明两个Class之间的继承关系,而instanceof则是实例对象和类之间关系的表示。同时对于instanceof关键字使用,若实例对象为null,不论实例对象是否进行强制转换,均返回false。
同时注意,BI.class.isAssignableFrom(null)会抛出空指针异常,使用Class参数进行isAssignableFrom方法判断时,Class均需增加非空判断。
Spring等框架源码中常见如上两种方式的使用,比如instanceof,在spring-context中的ApplicationContextAwareProcessor类中,常用用法是Spring的bean实现了ApplicationContextAware接口后,可以获取到Spring应用上下文ConfigurableApplicationContext applicationContext,通过((ApplicationContextAware)bean).setApplicationContext(this.applicationContext)方法,就可以在自定义bean中获取到上下文并调用getBean等方法获取bean。
源码参考如下:
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware)bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware)bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}