我怎么知道一个类是否是另一个类的超类,因为我只有类的完全限定名作为字符串?

时间:2015-05-08 17:28:12

标签: java eclipse-plugin eclipse-jdt

我需要知道一个字符串表示的类是否是另一个类的超类(直接或传递),也表示为字符串。例如:

String class1 = "java.lang.Object";
String class2 = "java.lang.Exception";

assertTrue( isSuperclass( class1, class2 ) );

我试图获取第二个类的IType并检查其superclassName。这就是我尝试的方式:

/**
 * Checks if class1 is directly or transitively superclass of class2.
 */
private boolean isSuperclass(final String class1, final String class2)
{
    try
    {
        String className = class2;
        while (className!=null)
        {
            final IType type = this.javaProject.findType(className);
            if (type == null)
            {
                break;
            }

            className = type.getSuperclassName();
            if (class1.equals(className))
            {
                return true;
            }
        }

        return false;
    }
    catch (final JavaModelException e)
    {
        throw new IllegalStateException(e);
    }
}

问题是getSuperclassName只返回类名,而不是它的完全限定名。出于这个原因,我无法在循环中再次调用javaProject.findType来检查class2的任何传递超类是否等于class1。

所以,如果我打电话:

isSuperclass( "java.lang.Throwable", "my.exceptions.Exception" )

它将返回false,因为

 javaProject.findType("my.exceptions.Exception").getSuperclassName() 

仅返回" ParentException",然后下一个调用将是

 javaProject.findType("ParentException") 

返回null IType,因为它不是类的完全限定名。只有在自己的应用程序中声明的类被分析时才会出现这种情况;对于API类,getSuperclassName返回完全限定名称。

我还想过通过ITypeBindings检查isSuperclass,但我不知道如何从完全限定名称String或IType中获取ITypeBinding。

关于我如何检查一个类是否是另一个类的超类的任何想法?

编辑:基于Class.forName的解决方案无法解决我的问题。

4 个答案:

答案 0 :(得分:2)

如果您实际上可以加载相关课程,可以使用Class#isAssignableFrom

Class c1 = Class.forName(class1);
Class c2 = Class.forName(class2);
if (c1.isAssignableFrom(c2)) {
    // c1 is a superclass or superinterface of c2
}

来自文档:

  

public boolean isAssignableFrom(Class<?> cls)

     

确定此Class对象表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是它们的超类或超接口。如果是,它返回true;否则返回false

例如:

String class1 = "java.lang.Object";
String class2 = "java.util.HashMap";
Class c1 = Class.forName(class1);
Class c2 = Class.forName(class2);
System.out.println(c1.isAssignableFrom(c2)); // true

Live Example

答案 1 :(得分:1)

由于您的问题中有IType,我假设您使用的是JDT。在这种情况下,您可以通过创建IType来查询ITypeHierarchie的所有超类型(类和接口)。

唯一需要注意的是java.lang.Object中不会包含ITypeHierarchie(请参阅ITypeHierarchy.getAllSupertypes的{​​{3}}),因此您需要检查一下分开。

if (class1.equals("java.lang.Object")
    return true;
ITypeHierarchy typeHierarchy = type.newTypeHierarchy(new NullProgressMonitor());
IType[] supertypes = typeHierarchy.getAllSupertypes(type);
boolean isSuperType = Arrays.asList(supertypes).stream().anyMatch(supertype -> {
    return supertype.getFullyQualifiedName().equals(class1);
});

答案 2 :(得分:0)

您可以做的一个选项是使用Class.forName()获取Class对象,然后使用obj.getSuperClass()obj.getCanonicalName()检查继承。以下程序演示了这一点:

    public static void main(String[] args) {
    try {
        Class str = Class.forName("java.lang.String");
        Class ex = Class.forName("java.lang.StringBuilder");
        Class superStr = str;
        Class superEx = ex;

        Boolean strIsSuperEx = false;
        Boolean exIsSuperStr = false;
        Boolean bothClassesExist = true;

        while((!strIsSuperEx && !exIsSuperStr) && bothClassesExist) {
            if (superStr != null) {
                superStr = superStr.getSuperclass();
            }
            if (superEx != null) {
                superEx = superEx.getSuperclass();
            }
            bothClassesExist = (superStr != null) && (superEx != null);
            if (superStr != null) {
                String canonicalName = superStr.getCanonicalName();
                String exName = ex.getCanonicalName();
                exIsSuperStr = exName.equals(canonicalName);
            }
            if (superEx != null) {
                String canonicalName = superEx.getCanonicalName();
                String strName = str.getCanonicalName();
                strIsSuperEx = strName.equals(canonicalName);
            }
        }

        if (strIsSuperEx) {
            System.out.println(str.getCanonicalName() + " is a superclass of " + ex.getCanonicalName());
        } else if (exIsSuperStr) {
            System.out.println(ex.getCanonicalName() + " is a superclass of " + str.getCanonicalName());
        } else {
            System.out.println("Neither class is a superclass of the other.");
        }

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

答案 3 :(得分:0)

根据T.J.的答案。克劳德,布莱恩的评论和this page中的代码,我建立了这个答案:

 <div class="profile">               
                <?php 
                  $query = new WP_query( 'pagename=blog' ); 
                    if ( $query->have_posts() ) {
                    while ( $query->have_posts() ){
                    $query->the_post();
                    echo '<h2 class="text-center">' . get_the_title() . '</h2>';                                
                       }
                     }
                  wp_reset_postdata();
                 ?>   
 </div><!--end blog-content -->