gpt4 book ai didi

java - Java中变量的定义是否缺少 'Diamond operator'?

转载 作者:行者123 更新时间:2023-11-30 02:43:25 24 4
gpt4 key购买 nike

几年前,当 Java7 已经发布一年左右时,我从 C# 回到了 Java - java 泛型在某些方面对我来说似乎很奇怪。

有一个我会一遍又一遍地回来,看到这两个答案的受欢迎程度......

  1. Difference between <? super T> and <? extends T> in Java
  2. What is PECS (Producer Extends Consumer Super)?

...似乎很多人(包括我)“自然地”会期望“通用集合”声明中的语法有不同的行为。考虑下面的代码示例...

注意:架构正确性超出了范围 - 假设 baseClassesStorage应该可用于外部世界的获取/添加

public class DummyClass {

public static class BaseClass {}

public static interface ListOfAtLeastBaseClasses<T extends BaseClass> extends List<T> {}

public ListOfAtLeastBaseClasses<?> baseClassesStorage;

public void addToStorage(BaseClass item) {
baseClassesStorage.add(item);
}
}

...来自非 Java 世界的典型程序员会认为 ListOfAtLeastBaseClasses<?> baseClassesStorage说“这是从 BaseClass 派生的项目的存储”,但此示例的编译在 baseClassesStorage.add(item) 处失败错误如下:

C:\Temp\...\DummyClass.java:14: error: no suitable method found for add(BaseClass)
baseClassesStorage.add(item);
^
method Collection.add(CAP#1) is not applicable
(argument mismatch; BaseClass cannot be converted to CAP#1)
method List.add(CAP#1) is not applicable
(argument mismatch; BaseClass cannot be converted to CAP#1)
where CAP#1 is a fresh type-variable:
CAP#1 extends BaseClass from capture of ?

此类行为的原因在两个 above mentioned answers 中有描述。 。

但是我应该怎样做才能以“正确”和“优雅”的方式实现我的用例?

我所知道的选项:

  1. “正确的 Java 方式”似乎是将变量声明为
    public ListOfAtLeastBaseClasses<BaseClass> baseClassesStorage;
    但这样我实际上对该“List”的下限有多余的定义 - 它已经在 ListOfAtLeastBaseClasses 类的“contract”中定义了。这里的另一个问题 - 如果在某个时间点我想更改 ListOfAtLeastBaseClasses 类的下限,那么我将需要遍历此类型的所有成员变量并更改它们的定义:(。

  2. 使用“原始”类型
    public ListOfAtLeastBaseClasses baseClassesStorage;
    这将编译,但会有效地删除类型检查并在构建过程中生成不需要的警告。

  3. ...还有什么可能? ...

    • ListOfAtLeastBaseClasses<?> baseClassesStorage; - 在 Java 中是不同的东西
    • ListOfAtLeastBaseClasses<> baseClassesStorage; - 编译错误
    • ListOfAtLeastBaseClasses<*> baseClassesStorage; - 编译错误

最佳答案

It seems that 'correct Java way' is declaring variable as

public ListOfAtLeastBaseClasses<BaseClass> baseClassesStorage;

but this way I actually have redundant definition of the lower bound of that 'List'

不是真的。当您定义泛型类型时,您是说此类的用户将能够声明如下变量:

ListOfAtLeastBaseClasses<Foo> listOfFoo;
ListOfAtLeastBaseClasses<Bar> listOfBar;

其中 Foo 和 Bar 必须是 BaseClass 的子类。 BaseClass 是一个上限。但通用类型的用户可以选择更具限制性的列表,从而仅接受 Foo 或 Bar 的实例。

当您将列表声明为

ListOfAtLeastBaseClasses<BaseClass>

您选择创建一个可以接受任何类型的 BaseClass 实例的列表。

我们可以想象一种特殊的语法来表示 ListofAtLeastBaseClasses<TheDefinedUpperBound> ,但这不是菱形运算符的用途,而且在我看来,这种特殊语法会引入不必要的复杂性。

关于java - Java中变量的定义是否缺少 'Diamond operator'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40949170/

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