我正在尝试使用Java的反射API并处理一些字段。现在我遇到了一个问题,如何识别我的字段类型。字符串很容易,只需执行myField.getType().equals(String.class)
。对于其他非派生类也是如此。但是如何检查派生类呢?例如,LinkedList
作为List
的子类。我找不到任何isSubclassOf(...)
或extends(...)
方法。我需要通过自己的方式遍历所有getSuperClass()
并找到我的超类吗?
我正在尝试使用Java的反射API并处理一些字段。现在我遇到了一个问题,如何识别我的字段类型。字符串很容易,只需执行myField.getType().equals(String.class)
。对于其他非派生类也是如此。但是如何检查派生类呢?例如,LinkedList
作为List
的子类。我找不到任何isSubclassOf(...)
或extends(...)
方法。我需要通过自己的方式遍历所有getSuperClass()
并找到我的超类吗?
boolean isList = List.class.isAssignableFrom(myClass);
通常情况下,List
(以上内容)应该被替换为superclass
,myClass
应该被替换为subclass
。Class
对象表示的类或接口是与指定的Class
参数表示的类或接口相同、超类或超接口。如果是,则返回true
;否则返回false
。如果此Class
对象表示原始类型,则如果指定的Class
参数恰好是此Class
对象,则此方法返回true
;否则返回false
。
参考资料:
a) 在编译时检查一个对象是否是你所知道的一个类或接口(包括子类或实现类)的实例:
boolean isInstance = someObject instanceof SomeTypeOrInterface;
示例:
assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);
b) 检查一个对象在运行时是否是某个类或接口(包括子类)的实例:
Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);
例子:
public boolean checkForType(Object candidate, Class<?> type){
return type.isInstance(candidate);
}
SUPERCLASS.isAssignableFrom(SUBCLASS)
。一开始这让我感到困惑,但考虑到命名,它其实很明显。 - codeplebSUPERCLASS.isExtendedBy(SUBCLASS)
这样的写法会更容易理解。 - Sean Patrick FloydisExtendedBy
是一个不好的名称,因为 CLASS.isAssignableFrom(CLASS)
会返回 true(因此 CLASS.isExtendedBy(CLASS)
也是如此)。这不是我所期望的。 - Qw3ry另一个选项是使用 instanceof:
Object o =...
if (o instanceof Number) {
double d = ((Number)o).doubleValue(); //this cast is safe
}
Class.isInstance(object)
http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isInstance%28java.lang.Object%29 - Sean Patrick FloydField
。但我只想“查看”我的类及其字段,不想“试用”它们。 - craeshinstanceof
也适用于父类(在这种情况下是 Number
)本身,而不仅仅是子类。 - lukaszrysinstanceof适用于实例,即对象。有时您想直接使用类进行操作。在这种情况下,您可以使用Class类的asSubclass方法。
以下是一些示例:
1)
Class o=Object.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
这将会很顺利,因为JFrame是Object的子类。c将包含一个表示JFrame类的Class对象。
2)
Class o=JButton.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
Class o=Serializable.class;
Class c=Class.forName("javax.swing.JFrame").asSubclass(o);
protected boolean isTypeOf(String myClass, Class<?> superClass) {
boolean isSubclassOf = false;
try {
Class<?> clazz = Class.forName(myClass);
if (!clazz.equals(superClass)) {
clazz = clazz.getSuperclass();
isSubclassOf = isTypeOf(clazz.getName(), superClass);
} else {
isSubclassOf = true;
}
} catch(ClassNotFoundException e) {
/* Ignore */
}
return isSubclassOf;
}
这是@schuttek答案的改进版本。它之所以更好,是因为它可以正确地返回原始类型的false (例如isSubclassOf(int.class, Object.class) => false),并且还可以正确地处理接口(例如isSubclassOf(HashMap.class, Map.class) => true)。
static public boolean isSubclassOf(final Class<?> clazz, final Class<?> possibleSuperClass)
{
if (clazz == null || possibleSuperClass == null)
{
return false;
}
else if (clazz.equals(possibleSuperClass))
{
return true;
}
else
{
final boolean isSubclass = isSubclassOf(clazz.getSuperclass(), possibleSuperClass);
if (!isSubclass && clazz.getInterfaces() != null)
{
for (final Class<?> inter : clazz.getInterfaces())
{
if (isSubclassOf(inter, possibleSuperClass))
{
return true;
}
}
}
return isSubclass;
}
}
一种递归方法,用于检查Class<?>
是否是另一个Class<?>
的子类...
protected boolean isSubclassOf(Class<?> clazz, Class<?> superClass) {
if (superClass.equals(Object.class)) {
// Every class is an Object.
return true;
}
if (clazz.equals(superClass)) {
return true;
} else {
clazz = clazz.getSuperclass();
// every class is Object, but superClass is below Object
if (clazz.equals(Object.class)) {
// we've reached the top of the hierarchy, but superClass couldn't be found.
return false;
}
// try the next level up the hierarchy.
return isSubclassOf(clazz, superClass);
}
}
class A {
int i = 10;
public String getVal() {
return "I'm 'A'";
}
}
class B extends A {
int j = 20;
public String getVal() {
return "I'm 'B'";
}
}
class C extends B {
int k = 30;
public String getVal() {
return "I'm 'C'";
}
}
//方法
public static boolean isInheritedClass(Object parent, Object child) {
if (parent == null || child == null) {
return false;
} else {
return isInheritedClass(parent.getClass(), child.getClass());
}
}
public static boolean isInheritedClass(Class<?> parent, Class<?> child) {
if (parent == null || child == null) {
return false;
} else {
if (parent.isAssignableFrom(child)) {
// is child or same class
return parent.isAssignableFrom(child.getSuperclass());
} else {
return false;
}
}
}
// 测试代码
System.out.println("isInheritedClass(new A(), new B()):" + isInheritedClass(new A(), new B()));
System.out.println("isInheritedClass(new A(), new C()):" + isInheritedClass(new A(), new C()));
System.out.println("isInheritedClass(new A(), new A()):" + isInheritedClass(new A(), new A()));
System.out.println("isInheritedClass(new B(), new A()):" + isInheritedClass(new B(), new A()));
System.out.println("isInheritedClass(A.class, B.class):" + isInheritedClass(A.class, B.class));
System.out.println("isInheritedClass(A.class, C.class):" + isInheritedClass(A.class, C.class));
System.out.println("isInheritedClass(A.class, A.class):" + isInheritedClass(A.class, A.class));
System.out.println("isInheritedClass(B.class, A.class):" + isInheritedClass(B.class, A.class));
//Result
isInheritedClass(new A(), new B()):true
isInheritedClass(new A(), new C()):true
isInheritedClass(new A(), new A()):false
isInheritedClass(new B(), new A()):false
isInheritedClass(A.class, B.class):true
isInheritedClass(A.class, C.class):true
isInheritedClass(A.class, A.class):false
isInheritedClass(B.class, A.class):false
public static boolean isSubClassOf(Class<?> clazz, Class<?> superClass) {
if(Object.class.equals(superClass)) {
return true;
}
for(; !Object.class.equals(clazz); clazz = clazz.getSuperclass()) {
if(clazz.getSuperclass().equals(superClass)) {
return true;
}
}
return false;
}
LinkedList
不是List
的子类,而是List
的一种实现方式。 - T.J. Crowder