我尝试创建工厂,这是代码:
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
语句失败了。
我怎样才能达到预期的行为?
答案 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);