Java 中是否有与 Typescript union 等效的功能?

4

我想从一个TypeScript代码库中建模一些接口和类。我想知道在Java中建模TypeScript联合类型的最佳方法。就像这样-

export type a = b | c | d | e | f;
export type b = {
    ..
}
export type c = {
    ..
}
..

在Java中,最好的建模方式是什么?

例如: Class A = Class B or Class C or Class D; 这意味着A可以是这些类中任何一个的对象。 我正在寻找类的解决方案。 但另一个例子是: export type numberString = string | number


1
如果我们这些Java人知道那是什么,或许能帮到你。你能解释一下它实际上是做什么的吗?也许给个使用它的实际例子? - undefined
@markspaceexport type Message = AudioMessage | VideoMessage | ImageMessage;所以这些Message/AudioMessage/...都是类。而Message可以是任何这些类的对象。 - undefined
很遗憾,在Java中没有与联合类型相对应的简洁解决方案。通常情况下,我们会使用一个共同的基类或接口(甚至是一个标记接口)。但是,如果你有一些没有共同根源的类型,无法将它们适配到新的层次结构中,这种方法就不起作用了。 - undefined
1
Java没有联合类型,也没有控制流类型缩小,所以在Java中不能像在TypeScript中那样使用联合类型。将这段代码正确地转换为Java将完全取决于实际的类型以及它们的使用方式。 - undefined
很奇怪,Java已经有了catch (IOException | InterruptedException e),它在catch子句的上下文中管理联合类型。如果类的返回类型与现代的switch模式匹配或重命名的类型转换相结合,例如if (a instanceof MyThing thing),那将是很好的,但似乎并不存在或正在计划中。 - undefined
1个回答

3
这在Java中不存在,但其他基于JVM的语言可能有这样的概念(Scala具有特质,因此它们拥有联合并非不可能)。
在Java中有替代方案:
1. 使用重载。 2. 使用泛型。 3. 使用接口(可能是最接近您所寻找的内容)。
(1)使用重载:如果您需要使用一个字符串或一个数字,则创建两个方法。
void foobar(int n) { ... }    
void foobar(String s) { ... }

注意其中的int不是Integer(原始类型与包装类型的区别)...
(2) 使用泛型:如果您需要该对象实现某个接口(作为方法类型参数):
Runnable  run1(Runnable runnable);
<E extends Runnable> E run2(E runnable);
<E extends Runnable & InterfaceA> E run3(E runnable);

run1run2基本相同:如果方法返回类型为void,那么E类型可能是无用的。

<E extends Runnable & InterfaceA>很少使用,但可以限制E,使其实现类/接口RunnableInterfaceA

(3):您可以使用接口;Java不支持多重继承,但支持默认方法和多个接口:

interface B {}
interface A extends B, C, D, E, F {...}

问题在于无法使 A 的实现继承自 B、C、...、F 的实现。虽然某些语言中称之为 trait,但 Java 并未提供此功能。您可以尝试使用委托来实现此功能:
class AImpl implements A {
  private final B b;
  public AImpl() {
    this.b = new BImpl();
  }
  public void methodOfB() {b.methodOfB();}
  // and so on
}

这对于数字和字符串以及任何无法更改继承模型(最终类、第三方类等)的类型都不起作用。

2
我有一种印象,认为联合类型存在是因为TypeScript不支持方法的重载。然而,这并不是联合类型的唯一或主要目的,函数的联合类型与重载的行为方式并不相似;函数的联合类型通常并不实用,因为在运行时无法区分各个函数类型。 - undefined
可能吧,我不会用TypeScript。也许那些学过两种语言并且理解联合类型用例的人会愿意编辑我的答案,而不是给它投反对票(答案很简单:Java中不存在联合类型)。 - undefined
1
Java确实有联合类型,尽管在非常有限的上下文中使用:catch(ThisException | ThatException e) {...} :-) 您提供的解决方案是目前最好的近似方法。 - undefined
1
不太确定Java是否将它们视为这样的情况。无论如何,Java 17/21和其他功能可能接近它们:switch的模式匹配将允许在最终调用者上实现类似的功能:https://openjdk.org/jeps/441。拥有这样的类型是不不可能的,它允许我们指示某个方法返回一组有限的类型,而不是`Object`。 - undefined
1
我什么也没说:https://docs.oracle.com/en/java/javase/17/docs/api/java.compiler/javax/lang/model/type/UnionType.html - undefined

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