具有两个类层次结构的通用类

6

我有以下Java泛型问题:

我有一个通用类,可以简单地描述为:

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

...代表与案例无关的代码。

对于类MyClass<T>而言,目前确切的类型T并不重要,但对于以下两个类:

  • AnotherClass<T>

  • OtherClass<T>

它们的泛型类型非常重要,将在运行时基于此做出决策。

基于这个,类型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所代表的实体相关联。

TMyClassAnotherClassOtherClass中是相同的,因此在一个实例中只有T_1T_2,但从未同时存在。

我的问题是,除了为MyClass设计一个接口并分别对T_1T_2进行实现之外,我还有哪些可选方案?

我能否像这样实现一些东西:MyClass<T extends T_1 or T_2>?

顺祝商祺


5
如果实际类型没有关联,为什么要在两个类中都使用通用 T 呢? - Tim
2
将其定义为 MyClass<T, U> 或甚至 MyClass<T, U, V> 有什么问题?这将允许您单独设置每种类型的边界。 - Robby Cornelissen
2
哦,好的。所以基本上你想要的是类似于 MyClass<T extends T1 or T2> 这样的东西? - Robby Cornelissen
2
这被称为“联合类型”,我认为Java没有它们(除了用于异常的catch块)。您需要使用一些包装器来模拟它。 - Thilo
3
如果T_1和T_2是不相交的,共同接口没有价值,那么可能需要在T_1和T_2周围创建包装类,暴露目前存储在MyClass、AnotherClass和OtherClass中的公共功能。然后有一个共同的接口。我担心当前类中会有instanceofs。 - Joop Eggen
显示剩余10条评论
2个回答

2

也许这并不完全符合您的需求,但您可以尝试一下:

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

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

  // Add any code needed

}

然后创建两个通用类,分别针对这两个基类。
如果所有代码都可以在抽象类中实现,则这些类可以为空:
public class MyT1Class<T extends T_1> extends MyClass<T>
{
}

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

我最终用两个“接口”完成了这个。谢谢。 - Jorge Lavín

0

我知道这不是一个很好的答案,但我不能把它留在问题的评论中。
您可以通过尝试以下操作在运行时检查类型:

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。您的代码使用了isAssignableFrom和一个if-then子句,这正是我想避免的。 - Jorge Lavín
@JorgeLavín 我已经猜到你想要一个设计时解决方案了。 - Robert Kock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接