繁体   English   中英

如何确定在Java中使用哪个通配符?

[英]how to decide which wildcard to use in java?

一种用途应扩展到哪里,一种用途应扩展到哪里,根本不适合使用通配符?

是他们的任何原则或规则,还是全部与自己的理解和适用范围有关。

像目前一样,我只需要在列表中添加两个数字即可使用,

 public List<Integer> addToNewList(integerList  , Integer element){
   integerList.add(element);
   return integerList;
}

但是后来我的应用程序范围增加了,现在它需要所有数字,因此请使其通用,以获得最大支持。 例如:

public <T extends Number> List<T> addToList(List<? extends T> genericList , T element){
   genericList.add(element);
   return genericList;
}

简而言之,我只想知道,什么时候应该使用这些通配符,什么时候不使用?

我了解何时使用和何时不使用,我在一本书中发现了一个很棒的原则:

获取和放置原则:仅当从结构中获取值时使用扩展通配符,仅将值放入结构中时使用超级通配符,而同时获取和放置时不使用通配符。

这是一种方法,它采用一组数字,将每个数字转换为双精度数字,然后求和:

public static double sum(Collection<? extends Number> nums) {
    double s = 0.0;
    for (Number num : nums) s += num.doubleValue();
    return s;
}

由于使用了扩展,因此以下所有调用都是合法的:

List<Integer>ints = Arrays.asList(1,2,3);
assert sum(ints) == 6.0;
List<Double>doubles = Arrays.asList(2.78,3.14);
assert sum(doubles) == 5.92;
List<Number>nums = Arrays.<Number>asList(1,2,2.78,3.14);
assert sum(nums) == 8.92;

如果不使用扩展,则前两个调用将不合法。

例外:不能将任何东西放入用扩展通配符声明的类型中,除了值null(属于每个引用类型)外。

每当使用add方法时,都会将值放入结构中,因此请使用超级通配符。 这是一个方法,该方法采用数字和整数n的集合,并将从零开始的前n个整数放入集合中:

public static void count(Collection<? super Integer> ints, int n) {
    for (int i = 0; i < n; i++) ints.add(i);
}

由于这使用super,因此以下所有调用都是合法的:

List<Integer>ints = new ArrayList<Integer>();
count(ints, 5);
assert ints.toString().equals("[0, 1, 2, 3, 4]");
List<Number>nums = new ArrayList<Number>();
count(nums, 5); nums.add(5.0);
assert nums.toString().equals("[0, 1, 2, 3, 4, 5.0]");
List<Object>objs = new ArrayList<Object>();
count(objs, 5); objs.add("five");
assert objs.toString().equals("[0, 1, 2, 3, 4, five]");

如果不使用super,则最后两个调用将不合法。

例外:您无法从使用超级通配符声明的类型中获取任何东西,除了Object类型的值(这是每种引用类型的超级类型)之外。

在以下问题“ 获取和放置”规则中也解释了此原理

当它们有意义时,您应该使用它们。

在您的实例中,您说过由于应用程序的发展,必须重构代码以将通用类型从整数更改为Number。 对我来说这完全可以。 几乎不可能期望应用程序的所有发展方式。 编写代码来处理“将来可能出现”的场景是徒劳的,直到它在将来到达那个时间为止,因为它可能根本没有到达那里。

话虽这么说,您应该尝试将API设计为最少限制的类型,以使您的功能可以正常运行。 除非当然需要大量的工作,否则当前的功能将无法提供所提供的灵活性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM