如何让一个通用的 class 方法只被某些类型的参数执行?

How to allow a generic class method to be executed only by certain types of parameters?

我正在尝试向现有 class BinaryTree<T> 添加一个方法,以简单地添加树中所有元素的值。问题是 class 是一个通用的,并不是所有在创建树时可以发送的类型都可以添加。我的意思是,例如尝试添加 class people.

的值没有任何意义

所以我的问题是,我如何制作一个方法 public T addAllElements() 只允许 T 成为一种特定类型,在这种情况下,只有可以添加它的类型值,例如 IntegerFloatLong 等?我想必须有某种数字接口或者语言提供的某种声明才能执行类似的操作。

顺便说一句,这似乎是一个无需创建子节点的解决方案 class,万一它可以帮助任何事情,因为我被要求解决类似的问题并且说明说该方法必须在相同的 class.

为了更清楚,我再问一个问题,因为我认为他们两个的答案相同。

我发现 java.util.Arrays class 中的方法 sort() 可以被 class 使用,如果 class 实现接口 Comparable<T>.所以如果我有 class,假设

public class People {
    implements Comparable<People>
    private String name;
    public int compareTo(People o) {
        ...
    }
    ...
}

这个 class 可以用 Arrays class 的 sort() 方法排序,但是如果 class 没有实现 Comparable<T> 接口它不能。那么,是什么在 Arrays class 定义中进行了此限制?是不是我问的第一个问题需要解决的?

So my question is, how do I make a method publicTaddAllElements() that only allows T to be an specific kind of type, in this case, only the types that is possible to add it's value, like int, float, long, etc? I guess there have to be some kind of numerical interface or maybe some kind of declaration provided by the language to do something like that.

您正在寻找 Number

因此,如果 class 是通用的,您的声明将如下所示:

public BinaryTree<T extends Number> {
  // ...
}

或者如果您只想使方法通用:

public <T extends Number> T addAllElements() {
  // ...
}

也就是说,无论好坏 Number 都没有根据方法定义算术运算。据我所知,没有这样的内置类型。

请注意,您列出的类型都是基本类型,这意味着它们与泛型根本不兼容。 Number 的子类型(以及可以与泛型一起使用的类型)都将是包装类型:IntegerFloatLong 等。

你的例子相关,但不一样。

首先要解决后一个问题,具有特定签名的 Arrays.sort 要求事物为 Comparable 的原因是因为它需要根据自然顺序对它们进行排序。您可以向该方法提供另一个签名,该方法允许您将自定义 Comparator 传递给它,以对您喜欢的 class 的任何其他 属性 进行排序。

您主要关心的是,您需要有一个上限泛型,特别是 T extends Number 类型之一。这样做的原因是 Number 是所有数字包装器 class 以及 BigDecimalBigInteger.[=30 的父级 class =]

在执行此操作之前,您需要确定两件事:

  • 您的泛型类型绑定在 class 级别。由于我们正在处理一棵树,因此在整个过程中使用非同类数据是没有意义的。
  • 您根据特定数据类型(intlongdouble)进行了数学运算。

然后您可以这样声明您的方法:

public int addAsInteger() {}
public double addAsDouble() {}
public long addAsLong() {}

您将使用 Number's methodsintValuelongValuedoubleValue 作为您各自的方法。

你不能简单地 return T 因为你不能保证 种类 Number返回,或者 T 具体绑定到什么(它不能是 Number 因为它是一个抽象的 class,所以它是一个非包含的上限)。