如何比较两个班级

时间:2016-07-06 10:59:10

标签: java generics reflection

我尝试创建工厂,这是代码:

public class MyFactory {
    public static <T> MyBase create(Class<T> _c) {
        if (_c.getClass().equals(Derived1.class)) // (1)
            return createNewDerived1();

        return null;
    }
}

// caller
MyFactory.create(Derived1.class);

它在第(1)行编译警告:

错误

'equals()' between objects of inconvertible types 'Class<Derived1>'
 and 'Class<capture of ? extends Class>' <br>Reports calls to .equals()
 where the target and argument are of incompatible types. While such a
 call might theoretically be useful, most likely it represents a bug.

在运行时,由于某种原因,我的if语句失败了。 我怎样才能达到预期的行为?

2 个答案:

答案 0 :(得分:3)

<div class="panel panel-primary" ng-show="myvalue">

有关详细信息,请参阅Compare class objects

FIY,&#34;真实&#34;类对象引用具有public class MyFactory { public static <T> MyBase create(Class<T> _c) { return ( _c == Derived1.class ) ? createNewDerived1() : null; } } // caller MyFactory.create(Derived1.class); 类型签名(在擦除之前),而Class<MyClass>类返回的Class是AFAIR,在某些环境中只是rawtype .class并且Class } -ish on others。

答案 1 :(得分:2)

您的代码问题

public static <T> MyBase create(Class<T> _c) {
    if (_c.getClass().equals(Derived1.class)) // (1)
        return createNewDerived1();

    return null;
}

您希望将_c所代表的类与文字Derived1.class进行比较,但您对getClass()对象进行了不必要的Class调用。在getClass对象上调用Class将返回表示类java.lang.Class的对象,您肯定不希望与Derived1进行比较,因此警告是一件好事

解决方案是删除getClass()调用。如果您使用身份比较替换equals==,就像在this answer中一样,那就不会受到影响。类始终由单个规范Class实例表示,因此equals==的语义对于Class个实例是相同的。

但请注意,您的通用签名值得怀疑。

如果提供的Class对象旨在指定所创建实例的类型,但返回类型始终为MyBase,那么您肯定希望将参数限制为MyBase。 },例如

public static <T extends MyBase> MyBase create(Class<T> _c) {
    if(c.equals(Derived1.class))
        return createNewDerived1();

    return null;
}

但你不需要这里的类型参数;将签名更改为

public static MyBase create(Class<? extends MyBase> _c)

具有相同的语义。

或者您决定指定返回的类型保证是参数指定的类型(如果这是意图)。然后,您应该将方法更改为

public static <T extends MyBase> T create(Class<T> _c) {
    return c==Derived1.class? _c.cast(createNewDerived1()): null;
}

public static <T extends MyBase> T create(Class<T> _c) {
    return c==Derived1.class? _c.cast(createNewDerived1()): _c.newInstance();
}

你可以使用

Derived1 obj = MyFactory.create(Derived1.class);