是否可以缩小Java类中字段的类型而不使包含类本身通用?
通用示例如下:
abstract class MyClass {
//...
}
interface MyInterface {
//...
}
class MyConcreteClass<T extends MyClass & MyInterface> {
private T value;
}
有没有办法做到以下几点:
class MyConcreteClass {
private MyClass & MyInterface value;
}
这基本上等同于MyConcreteClass或原始MyConcreteClass类型。在我的实现中,类型参数会随着对象的生命周期而变化(被诅咒的可变性!JPA强加给我!)因此类型注释似乎有些多余。
我忘记提及另外一项限制。我们也会这样:
class SubA extends MyClass
class SubB extends MyClass
class SubC extends MyClass
class SubSubA extends SubA implements MyInterface
class SubSubB extends SubB implements MyInterface
class SubSubC extends SubC implements MyInterface
因此,简单地声明实现MyInterface的MyClass的抽象子类不是一个合适的解决方案。
此外,最终字段类型必须是具体类型,而不是简单的表示交集的接口,原因很简单,因为JPA-persisted entites不能通过它们的接口类型引用。也就是说,JPA实体类中的持久字段必须是基本类型或具体实体类型。
答案 0 :(得分:2)
我从未遇到过这样的问题(因此没有想到优雅的解决方案: - )......然而......
interface Fooable
{
}
abstract class MyClass
implements Fooable
{
}
interface MyInterface
extends Fooable
{
}
class MyConcreteClass
{
private Fooable value;
}
答案 1 :(得分:1)
在这种复杂的情况下,你应该隐藏接口背后的类。
然后,您可以为交集定义一个显式接口,即扩展与MyClass和MyInterface对应的接口的接口,并让相应的超类实现它而不是MyInterface。
答案 2 :(得分:0)
我认为没有办法做到这一点。反正不是那样的。但是,由于这是一个私有字段并且您完全控制它,因此您可以将其声明为
private MyClass value;
但是也要确保在所有代码中只有实现MyInterface的对象会受到影响,并且只需要将它作为接口访问它。是的,看起来很脏,而且(稍微)。
您还可以创建以下派生类
abstract class MyDerivedClass extends MyClass implements MyInterface {
//...
}
然后使用
private MyDerivedClass value;
这个更干净,但你必须创建另一个类,只是为了这个目的......