如何只允许某些类型的参数执行泛型类方法?

时间:2015-05-15 00:30:01

标签: java generics polymorphism

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

所以我的问题是,我如何制作一个方法public T addAllElements(),只允许T成为特定类型的类型,在这种情况下,只有可以添加它的类型&#39 ; s值,如IntegerFloatLong等?我想必须有某种数字界面,或者可能是语言提供的某种声明来做类似的事情。

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

为了更清楚,我会问另一个问题,因为我认为他们都有相同的答案。

我发现如果类实现了接口sort(),则java.util.Arrays类中的方法Comparable<T>可以被类使用。所以,如果我上课,请说

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

可以使用sort()类中的Arrays方法对此类进行排序,但如果该类没有实现Comparable<T>接口,则无法实现。那么在Arrays类定义中有什么限制呢?这是我解决我问的第一个问题所需要的吗?

2 个答案:

答案 0 :(得分:2)

  

所以我的问题是,如何创建一个方法public T addAllElements()只允许T成为特定类型的类型,在这种情况下,只有可以添加它的类型价值,如intfloatlong等?我想必须有某种数字界面,或者可能是语言提供的某种声明来做类似的事情。

您正在寻找Number

因此,如果该类是通用的,那么您的声明将如下所示:

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

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

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

尽管如此,无论好坏,Number都没有根据方法定义算术运算。据我所知,没有这样的内置类型。

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

答案 1 :(得分:2)

您的示例相关,但它们并不相同。

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

对于您的主要关注点,您需要具有上限泛型,特别是类型T extends Number之一。原因是Number是所有数字包装类的父类,以及BigDecimalBigInteger

在你这样做之前,你需要确定两件事:

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

然后您将声明您的方法:

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

您可以使用Number's methodsintValuelongValuedoubleValue来处理各自的方法。

您无法简单地返回T,因为您无法保证您回来的Number种类,或T是特定绑定的(它不能是Number,因为它是一个抽象类,所以它是一个非包含的上限。)