gpt4 book ai didi

java - 协变返回类型最佳实践

转载 作者:行者123 更新时间:2023-11-30 10:06:14 24 4
gpt4 key购买 nike

我依稀记得在大学里学习方法的返回类型应该尽可能地窄,但我在网上搜索任何引用资料都没有找到,SonarQube 称之为代码味道。例如。在下面的示例中(注意 TreeSetSet 只是示例)

public interface NumberGetter {
Number get();

Set<Number> getAll();
}

public class IntegerGetter implements NumberGetter {

@Override
public Integer get() {
return 1;
}

@Override
public TreeSet<Number> getAll() {
return new TreeSet<>(Collections.singleton(1));
}
}

SonarQube 告诉我

Declarations should use Java collection interfaces such as "List" rather than specific implementation classes such as "LinkedList". The purpose of the Java Collections API is to provide a well defined hierarchy of interfaces in order to hide implementation details. (squid:S1319)

我明白隐藏实现细节的意义所在,因为我无法在不破坏向后兼容性的情况下轻松更改 IntegerGetter::getAll() 的返回类型。但通过这样做,我还为消费者提供了潜在有值(value)的信息,即他们可以更改他们的算法以更适合使用 TreeSet。如果他们不关心这个属性,他们仍然可以使用 IntegerGetter(无论他们如何获得它),就像这样:

Set<Number> allNumbers = integerGetter.getAll();

所以我有以下问题:

  • IntegerGetter::get() 返回更窄的类型是否合适?
  • IntegerGetter::getAll() 返回更窄的类型是否合适?
  • 关于这个主题是否有任何最佳实践,或者答案是否只是“视情况而定”?

(请注意,如果我将 TreeSet 替换为例如 SortedSet,SonarQube 不会提示。这段代码的味道是否只是因为没有使用 Collection API 接口(interface)?如果只有针对我的特定问题的具体类?)

最佳答案

返回类型必须在调用者的需要和实现的需要之间取得平衡:你告诉调用者关于返回类型的信息越多,以后更改该类型的难度就越大。

哪个更重要,要视具体情况而定。你见过这种类型的变化吗?了解来电者的类型有多大值(value)?

IntegerGetter.get() 的情况下,如果返回类型发生变化,那将是非常令人惊讶的,所以告诉调用者没有坏处。

IntegerGetter.getAll() 的情况下,这取决于调用者使用该方法的目的:

  • 如果他只想迭代,Iterable 将是正确的选择。
  • 如果我们需要更多方法,例如大小,Collection 可能。
  • 如果他依赖于唯一的数字,Set
  • 如果他还依赖于被排序的数字,则 SortedSet
  • 如果它确实需要来自 JDK 的红黑树,以便它可以直接操纵其内部状态以进行丑陋的黑客攻击,TreeSet 可能是正确的选择。

关于java - 协变返回类型最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54755518/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com