这是一种类似于您可能见过的其他 JPA BaseEntity 模式的设计:
@MappedSuperclass()
public abstract class Entity<X extends Entity<X>>
implements
Comparable<X>,
Serializable
{
private static final long serialVersionUID = 1L;
private Long id;
private Date timeStamp;
...
// Simply compare fields in subclass until difference is discovered
private int compareSubclassFields(X that)
{
int result = 0;
for(Comparator<X> comparator : getComparators())
{
result = comparator.compare(this,that); <<=== compilation error
if(result != 0) { break; }
}
return result;
}
/**
* Entity subclasses provide a list of their own special
* comparators that can contribute to the comparison.
*/
protected abstract List<Comparator<X>> getComparators();
}
下面是一个扩展 Entity 的类的例子:
public class User extends Entity<User>
{
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
private String email;
...
@Override
public List<Comparator<User>> getComparators()
{
List<Comparator<User>> result =
new ArrayList<Comparator<User>>();
result.add(getLastNameComparator()); // Sort first on last name
result.add(getFirstNameComparator());// Next, by first name
result.add(getEmailComparator()); // Finally, by email (unique)
return result;
}
}
当我编译时,我收到以下错误:
error: method compare in interface Comparator<T> cannot be
applied to given types;
result = comparator.compare(this,that);
^
required: X,X
found: Entity<X>,X
reason: actual argument Entity<X> cannot be converted to
X by method invocation conversion
where X,T are type-variables:
X extends Entity<X> declared in class Entity
T extends Object declared in interface Comparator
阅读Java Enum Definition,特别是它所说的部分,
public class StatusCode extends Enum<StatusCode>
现在,如果您检查约束,我们得到了 Enum - 所以 E=StatusCode。让我们检查一下:E 是否扩展了 Enum?是的!我们没事。
我假设在我的示例中,其中X extends Entity<X>
'this' 将是User
and not的一个实例Entity<User>
。此外,由于 Entity 是一个抽象类,它必须被扩展,因此compareNonIdFields
只能由 X 的实例调用——在它自身上。当然,当我施放时,我会收到未经检查的警告:
warning: [unchecked] unchecked cast
result = comparator.compare(((X)this),that);
^
required: X
found: Entity<X>
where X is a type-variable:
X extends Entity<X> declared in class Entity
1 warning
关于为什么这种递归通用用法会导致编译错误以及使未经检查的强制转换警告消失的解决方案的想法将不胜感激。