代码之家  ›  专栏  ›  技术社区  ›  Kris Nuttycombe

缩小Java字段类型而不使封闭类成为泛型?

  •  1
  • Kris Nuttycombe  · 技术社区  · 17 年前

    一般示例如下所示:

    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
    

    此外,最终字段类型必须是具体类型,而不仅仅是表示交叉点的接口,原因很简单,JPA持久化实体不能被其接口类型引用。也就是说,JPA实体类中的持久字段必须是基元类型或具体实体类型。

    3 回复  |  直到 17 年前
        1
  •  2
  •   TofuBeer    17 年前

    我从来没有遇到过这样的问题(因此没有一个优雅的解决方案出现在我的脑海中:-)。。。然而

    interface Fooable 
    {
    }
    
    abstract class MyClass 
        implements Fooable 
    {
    }
    
    interface MyInterface 
        extends Fooable 
    {
    }
    
    class MyConcreteClass 
    {
        private Fooable value;
    }
    
        2
  •  1
  •   starblue    17 年前

        3
  •  0
  •   Varkhan    17 年前

    我认为没有办法做到这一点。反正也不是那样的。但是,由于这是一个私有字段,您可以完全控制它,因此可以将其声明为

     private MyClass value;
    

    但也要确保在所有代码中,只有实现MyInterface的对象才受其影响,并在需要访问MyInterface作为接口的任何地方强制转换。是的,它看起来很脏,而且(有点脏)。

    您还可以创建以下派生类

    abstract class MyDerivedClass extends MyClass implements MyInterface {
        //...
    }
    

    然后使用

     private MyDerivedClass value;
    

    这要干净得多,但您必须创建另一个类,仅用于此目的。。。