【问题标题】:Is it possible to check if one class is extending another in java without making instances?是否可以在不创建实例的情况下检查一个类是否在 java 中扩展另一个类?
【发布时间】:2021-03-12 22:32:10
【问题描述】:

我有两个Class<? extends SomeClass> 变量,一个通过循环HashMap 的键获得,我们称之为A,另一个作为参数传递,我们称之为B。我想看看B 是否扩展A。

所以,就我目前的理解而言,我会创建一个B 的实例(使用createInstance)并检查instanceof。但这不仅很慢,而且很麻烦,因为类需要一个空的构造函数。 请参阅here 和here,他们在其中讨论isAssignableFrom 和getSuperClass,但isAssignableFrom(从我在那里读到的内容)不适用于同一类(SomeClass.isAssignableFrom(SomeClass) ?),并且getSuperClass 不会上树。

有没有一种方法可以检查B 是否扩展A 而无需创建B 的实例?

例如:

class SomeClass {}
class ExtendingClassA extends SomeClass {}
class ExtendingClassAB extends ExtendingClassA {}
class ExtendingClassB extends SomeClass {}
boolean ClassExtendsClass(Class<? extends SomeClass> A,Class<? extends SomeClass> B) {
    return A.class instanceof B.class;
}
ClassExtendsClass(SomeClass.class, ExtendingClassA.class); //true
ClassExtendsClass(SomeClass.class, ExtendingClassAB.class); //true
ClassExtendsClass(SomeClass.class, ExtendingClassB.class); //true
ClassExtendsClass(ExtendingClassA.class, ExtendingClassB.class); //false

【问题讨论】:

  • 我没有看到您描述的问题。如果B extends A,则A.class.isAssignableFrom(B.class) 将是true。相反,B.class.isAssignableFrom(A.class) 将是false 应该是,因为B 不是A 的超类(也不是同一个类)。 B.class.isAssignableFrom(B.class) 也将是 true(A 相同)
  • getSuperClass 自己也不会上树,但你可以带着它上树。
  • @Rogue 是的,我想检查 B 是否扩展了 A,以及 B 是否是 A
  • @LouisWasserman 好主意,我会为此使用while 循环吗?喜欢while(c = c.getSuperClass())?
  • @Werilous 再次考虑相反的情况。当且仅当(B extends A 或B == A)时A.class.isAssignableFrom(B.class) 为真。没有理由不使用#isAssignableFrom,它正是您正在寻找的功能。同样,如果您拥有的是A 和B 的objects,则完全放弃Class&lt;?&gt;-es,只使用instanceof

标签: java inheritance multiple-inheritance


【解决方案1】:

是的。通常,检查您认为合适的类型的 API (javadoc)。在这种情况下,就是Class 本身,幸运的是,it's there:

Class<?> a = Integer.class;
Class<?> b = Number.class;
System.out.println(b.isAssignableFrom(a));
System.out.println(b.isAssignableFrom(b));
> true
> true

但是 isAssignableFrom (从我在那里读到的)在同一个类上不起作用

您应该在做出假设之前测试这些东西。它工作正常。

【讨论】:

  • 明白了,我很感激。我为之前没有看到这一点而感到倾倒,哈哈。而且我认为从讨论中,我应该自己测试它。
  • 阅读the first line of the method's javadoc 会受益于讨论中的这些人,其中说“确定此 Class 对象表示的类或接口是否与...相同”
  • @Rogue 是的,我同意,我自己也错过了同一行(你可以告诉哈哈)
【解决方案2】:

您可以递归地对类对象使用 getSuperclass 方法,直到没有更多的超类:

class A {}
class B extends A {}
class C extends B {}

public class Main {
    public static void main(String[] args) {
        Class clazz = C.class;

        System.out.println(clazz.getClass());
        System.out.println(clazz.getSuperclass());
        System.out.println(clazz.getSuperclass().getSuperclass());
        System.out.println(clazz.getSuperclass().getSuperclass().getSuperclass());
        System.out.println(clazz.getSuperclass().getSuperclass().getSuperclass().getSuperclass());
    }
}

上面的例子会产生

class java.lang.Class
class B
class A
class java.lang.Object
null

【讨论】:

  • 笨拙,不适用于接口。 isAssignableFrom 怎么了?
  • 感谢您解释 getSuperClass 的行为,但可以将其与问题联系起来以使其成为完整的答案吗?
  • @rzwitserloot 没什么,我没说有什么问题,事实上,我只是从你的回复中得知的。
  • 虽然学习很好,但我个人会避免将其作为答案。 #getSuperClass 只会上一步,而#isAssignableFrom 会检查关系的有效性,通常是更相关的信息。
猜你喜欢
  • 2016-03-11
  • 2012-02-07
  • 1970-01-01
  • 2013-04-09
  • 2022-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
相关资源
最近更新 更多