【问题标题】:Java Generics With Any Type <?>任何类型的 Java 泛型 <?>
【发布时间】:2014-03-13 22:04:37
【问题描述】:

我正在尝试用 Java 编写一个方法,该方法能够将自定义 Key 对象添加到数组中,或者更改数组中已经存在的键(如果有的话)。但是,我似乎无法让它工作。键将使用的类型主要是字符串和整数,但我的通用方法似乎不起作用。

setValue()方法的参数类型为T,getValue()返回T。

public void set(Key<?> key) {
    for (int i = 0; i < settings.size(); i++) {
        Key<?> k = settings.get(i);
        if (k.getName().equals(key.getName())) {
            k.setValue(key.getValue()); // Error here
            break;
        }
    }
    settings.add(key);
}

错误(我使用的是 Eclipse)是:

The method setValue(capture#4-of ?) in the type Key<capture#4-of ?>
is not applicable for the arguments (capture#5-of ?)

【问题讨论】:

  • 一个是Key&lt;Integer&gt;,另一个是Key&lt;String&gt;,这怎么用!?
  • @BoristheSpider 那么 if 语句会返回 false 吗?
  • 设置初始化为什么?
  • 编译器是怎么知道的?
  • 您需要将接收者和生产者 both 强制转换为相同的类型。通过将泛型类型声明为&lt;?&gt;,您声明您不关心该类型。您可以使用Object,但您不能提供,因为它可以是任何类型。例如,如果你要将k 转换为Key&lt;Object&gt;,你可以设置任何东西。但如果k 实际上是Key&lt;Integer&gt;,那么您稍后会得到一个随机的ClassCastException

标签: java generics wildcard


【解决方案1】:

您不能向 java 保证,如果您为您的 set() 方法提供了一个 Key 对象,并且数组中还有另一个具有相同名称的 Key 对象,那么它们将具有相同的类型参数。所以java不能在编译时检查你代码的类型安全。

所以,我认为,你应该在这里使用Raw Types

【讨论】:

    【解决方案2】:

    Philip 的诊断是正确的,但您仍然应该能够声明一个泛型类型然后使用它。在你的情况下,

    public <T> void set(Key<T> key) {
        for (int i = 0; i < settings.size(); i++) {
            Key<T> k = settings.get(i);
            if (k.getName().equals(key.getName())) {
                k.setValue(key.getValue()); // Error here
                break;
            }
        }
        settings.add(key);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多