关于Class.isInstance的困惑

时间:2014-02-24 15:10:46

标签: java class

在java中是否可以获得对象的完整层次结构? 我检查了类的javadoc,我找不到这样的方法。 另外,我觉得奇怪的是以下代码的结果:

public static void main(String[] args) throws ClassNotFoundException {
    ClassLoader loader = ClassLoaderTest.class.getClassLoader();
    Class<?> clazz = loader.loadClass("java.lang.Integer");
    System.out.println(clazz.getSuperclass()); //prints java.lang.Number
    System.out.println(clazz.isInstance(clazz.getSuperclass())); //returns false??

    Number number = new Integer(1);//no class cast exception
}

isInstance()方法的doc说:

  

确定指定的{@code Object}是否与赋值兼容        *使用此{@code Class}表示的对象。

因为我们可以将Integer分配给Number,为什么:

java.lang.Integer.class.isInstance(java.lang.Number.class);

返回false?

THX

2 个答案:

答案 0 :(得分:1)

重新引用javadoc

  

确定指定的Object是否与赋值兼容*   使用此Class表示的对象。

在表达式

java.lang.Integer.class.isInstance(java.lang.Number.class);

您正在检查表达式java.lang.Number.class返回的对象是否是Integer的实例。 不是,它是java.lang.Class的实例。

应该像

一样使用
java.lang.Integer.class.isInstance(new Integer(1)); // if you want it to return true

你可以传递任何你想要的东西,但是如果使用的参数是true或其子类型之一,它只会返回Integer(但它是final所以没有& #39; t any)。

IntegerNumber的子类型。

任何Integer实例都可以在需要Number对象的地方使用。

答案 1 :(得分:0)

为了获得“完整的层次结构”,您可以递归地从起始类遍历其所有超级域及其实现的接口

import java.util.LinkedHashSet;
import java.util.Set;

public class Superclasses
{
    public static void main(String[] args)
    {
        Class<?> c = Integer.class;

        System.out.println("Superclasses:");
        Set<Class<?>> superclasses = superclasses(c);
        for (Class<?> s : superclasses)
        {
            System.out.println(s);
        }
    }

    private static Set<Class<?>> superclasses(Class<?> c)
    {
        LinkedHashSet<Class<?>> set = new LinkedHashSet<Class<?>>();
        superclasses(c, set);
        return set;
    }

    private static void superclasses(Class<?> c, Set<Class<?>> set)
    {
        if (c == null)
        {
            return;
        }
        set.add(c);
        if (c.equals(Object.class))
        {
            return;
        }
        superclasses(c.getSuperclass(), set);
        for (Class<?> i : c.getInterfaces())
        {
            superclasses(i, set);
        }
    }

}

请注意,当您想要获取泛型超类时,情况稍微复杂一些。例如,当您拥有类似List<Integer>的类并希望获得包括Collection<? extends Number>Iterable<? extends Serializable>在内的所有超类时。我已经实现了这一点,但这有点麻烦,因为这种意义上的超类集是无限的,你必须在某个地方停下来......