Java反射,判断Class是否为某个类的子类或父类

最近在项目里调用的一个类库,返回值是一个Class类型,我想判断一下这个Class对象是否为某个Class的子类或者父类,经过一番搜索,发现了一篇被转了很多次的文章,但是据我自己测试感觉存在一些问题,所以就直接拿别人文章的名字做了我写这篇文章的题目,文章的具体地址在文末的参考文章里。

​ 首先写几个类说明一下它们的关系。

class A {
}

class B extends A {
}

class C extends A {
}

class D extends B {
}

instanceof

​ 如果不用反射,平时判断一个类是否为某个类的子类,通常都用instanceof来判断。

public class TestInstanceOf {
	public static void main(String[] args) {
		A a = new A();
		B b = new B();
		C c = new C();
		D d = new D();
		System.out.println(a instanceof A);
		System.out.println(b instanceof A);
		System.out.println(c instanceof A);
		System.out.println(d instanceof B);
		System.out.println(d instanceof A);
	}
}

结果当然输出的都是true,不过这篇文章主要是想讨论使用Class类的isAssignableFrom方法。

isAssignableFrom

public class TestClass {
	public static void main(String[] args) {
		System.out.println(A.class.isAssignableFrom(A.class)); //true
		System.out.println(A.class.isAssignableFrom(B.class)); //true
		System.out.println(B.class.isAssignableFrom(A.class)); //false
		System.out.println(A.class.isAssignableFrom(C.class)); //true
		System.out.println(A.class.isAssignableFrom(D.class)); //true
	}
}

刚开始我想知道isAssignableFrom用法的时候产生了一些疑惑,从方法名上看带有From,就先入为主的认为参数传递的应该是子类的Class,但写了程序测试发现似乎不太对,然后就进入到源码(jdk14)里去看,如下:

/**
     * Determines if the class or interface represented by this
     * {@code Class} object is either the same as, or is a superclass or
     * superinterface of, the class or interface represented by the specified
     * {@code Class} parameter. It returns {@code true} if so;
     * otherwise it returns {@code false}. If this {@code Class}
     * object represents a primitive type, this method returns
     * {@code true} if the specified {@code Class} parameter is
     * exactly this {@code Class} object; otherwise it returns
     * {@code false}.
     *
     * <p> Specifically, this method tests whether the type represented by the
     * specified {@code Class} parameter can be converted to the type
     * represented by this {@code Class} object via an identity conversion
     * or via a widening reference conversion. See <em>The Java Language
     * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
     *
     * @param     cls the {@code Class} object to be checked
     * @return    the {@code boolean} value indicating whether objects of the
     *            type {@code cls} can be assigned to objects of this class
     * @throws    NullPointerException if the specified Class parameter is
     *            null.
     * @since     1.1
     */
    @HotSpotIntrinsicCandidate
    public native boolean isAssignableFrom(Class<?> cls);

一看已经到native方法,那就先看看注释吧,注释的描述也是看的我云里雾里的。Determines if the class or interface represented by this
{@code Class} object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified
{@code Class} parameter. 有些复杂,那就简化一下,大致可以简化成这样Determines if the class represented by this Class object is a superclass of the class represented by the specified Class parameter. 这样就清晰多了,也就是说参数传入的应该是子类。

然后再说到我看到的这篇被很多人转发的参考文章,其中它里面的类是这么写的

class T{
	List<A>  a;
	List<B>  b;
	Map<Integer, String> map ;
	int c;
}
class A {}
class B{}

测试的main函数里面有一段是这么写的

//fc是遍历Class T对象里所有的成员变量
//fc会是a,b,map,c的类型
if(fc.isAssignableFrom(List.class)) {
}

这篇文章里的执行程序之所以是正确的是因为fc本身就是List类型,但是如果将T里的List类型改为ArrayList,那就判断不出来了,而ArrayList是实现了List的接口的。我觉得原作者这么写,很有可能就是像我刚开始一样,看到了这个函数名中有From这个单词。

当然我写这篇文章,并不是为了批评参考文章中的作者,只是作为一种技术探讨,共同进步。

参考

  1. https://blog.csdn.net/is_zhoufeng/article/details/7629931
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值