【问题标题】:Generic class with two class hierarchies具有两个类层次结构的通用类
【发布时间】:2018-09-06 07:45:21
【问题描述】:

我有以下 Java 泛型问题

我有以下泛型类,可以概括为:

public class MyClass<T> {
    AnotherClass<T> another;
    OtherClass<T> other;
    ...
}

其中... 表示与案例无关的代码。

对于MyClass&lt;T&gt; 类而言,T 的确切类型并不重要(截至目前),但对于两者而言:

  • AnotherClass&lt;T&gt;

  • OtherClass&lt;T&gt;

绝对至关重要什么是泛型类型,并且将在运行时基于此做出决策。

基于此,T 类型不是完全任意的,它可以是类T_1 的层次结构的实例,也可以是类T_2 的层次结构的实例。

按照类的定义,T 类型等同于Object,但我知道它等同于T_1T_2

实体T_1T_2 之间没有业务关系,因此我不这样做:

public interface BaseT { ... }
public class T_1 implements BaseT { ... }
public class T_2 implements BaseT { ... }

public class MyClass<T extends BaseT>

如果它们不相关,为什么要使用泛型:

我正在为两者定义(尝试)一个通用类,因为即使它们明确地不相关,也存在隐式关系,因为T_1T_2 可以并且将出现与MyClass 中表示的实体相关联

T 对于 MyClassAnotherClassOtherClass 将是相同的,因此在一个实例中只会有 T_1T_2,但绝不会同时出现两者。

我的问题是,除了设计一个 MyClass 的接口并为 T_1T_2? 实现它。

我可以实现类似MyClass&lt;T extends T_1 or T_2&gt; 的东西吗?

亲切的问候

【问题讨论】:

  • 如果实际类型不相关,为什么要对两个类都使用泛型 T?
  • 将其定义为MyClass&lt;T, U&gt; 甚至MyClass&lt;T, U, V&gt; 有什么问题?这将允许您分别设置每种类型的边界。
  • 哦,好的。所以基本上你追求的是MyClass&lt;T extends T1 or T2&gt;?
  • 这被称为“联合类型”,我认为 Java 没有它们(catch 块除外)。您需要使用一些包装器来模拟它。
  • 如果 T_1 和 T_2 是一个公共接口没有价值的分离,那么可能应该围绕 T_1 和 T_2 创建包装类,以公开当前存储在 MyClass、AnotherClass、OtherClass 中的公共功能.然后有一个通用的接口。恐怕目前类中会有instanceofs。

标签: java oop generics design-patterns


【解决方案1】:

这可能不是您想要的,但您可以试一试:

创建一个实现所有内容的abstract 泛型类:

public abstract class MyClass<T>
{
  AnotherClass<T> another;
  OtherClass<T> other;

  // Add any code needed

}

然后为两个基类创建 2 个通用类。
如果所有代码都可以在抽象类中实现,则这些类可能为空:

public class MyT1Class<T extends T_1> extends MyClass<T>
{
}

public class MyT2Class<T extends T_2> extends MyClass<T>
{
}

【讨论】:

  • 我最终这样做了,有两个interfaces。谢谢
【解决方案2】:

我知道这不是一个很好的答案,但我不能将其作为对该问题的评论。
您可以通过尝试以下方法在运行时检查类型:

public class MyClass<T>
{
  // This factory-method creates an instance of the class if the correct type is passed
  // It throws a RuntimeException if not.
  public static <T> MyClass<T> getInstance(Class<T> type)
  {
    if (T_1.class.isAssignableFrom(type) || T_2.class.isAssignableFrom(type))
      return (new MyClass<T>());
    else
      throw new RuntimeException("Cannot create instance of MyClass<" + type.getName() + ">");
  }

  ...

}

然后

class T_3 extends T_2
{
}

....

MyClass<T_3> test_1;
test_1 = MyClass.getInstance(T_3.class); // This will succeed

MyClass<String> test_2;
test_2 = MyClass.getInstance(String.class); // Fails

【讨论】:

  • 谢谢@RobertKock。您的代码使用 isAssignableFromif - then 子句,这是我试图避免的。
  • @JorgeLavín 我已经猜到你想要一个设计时解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
相关资源
最近更新 更多