我需要知道一个字符串表示的类是否是另一个类的超类(直接或传递),也表示为字符串。例如:
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的解决方案无法解决我的问题。
答案 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
答案 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 -->