7

我想实现一个在scala(2.9.2)中使用泛型的java方法。但是我失败了...

Java接口方法:

public <T extends Number> void setAttribute(Key<T> key, Number value);

想要实现该方法的 Scala 代码:

def setAttribute[T <: Number](key: Key[T], value: Number) = {
  setAttributeLocal(key, value)  }

private def setAttributeLocal[T](key: Key[T], value: T) = {
  val stringValue = ConvertUtils.convert(value, classOf[String]).asInstanceOf[String]
  session = session + (key.getValue() -> stringValue)
}

键看起来像:

public class Key<T>

但这不会编译。

[error]  found   : mypackage.Key[T]
[error]  required: mypackage.Key[java.lang.Number]
[error] Note: T <: java.lang.Number, but Java-defined class Key is invariant in type T.
[error] You may wish to investigate a wildcard type such as `_ <: java.lang.Number`. (SLS 3.2.10)
[error]     setAttributeLocal(key, value)

我不知道有什么问题。有什么建议/想法吗?

格力加菲猫克隆

4

3 回答 3

4

编译器似乎对您对setAttributeLocal. setAttributeLocal需要 a Key[Number],但您提供的是Key[_ <: T]. 在 Java-Land 中,这意味着您试图将 a 传递Key<? extends Number>Key<Number>.

建议是setAttributeLocal接受Key<? extends Number>Key[_ <: Number],这取决于它是 Java 还是 Scala 定义的。

于 2012-07-30T14:29:33.807 回答
1

这里看起来有点不对劲。

你有没有尝试过:

def setAttribute[T <: Number](key: Key[T], value: T) =
  setAttributeLocal(key, value)

为键保留类型 T 似乎很奇怪/不好,但不在值上使用它。我的猜测是你会得到一个不变的错误。您正在尝试将 type 的值分配给 typeNumber的键,T编译器不确定它是否不能通过Numberfor T(虽然它知道它可以通过Tfor Number)。

我们可以看到更多代码吗?

于 2012-07-30T14:55:14.347 回答
1

正如@jsuereth 已经指出的那样, and 的签名之间存在差异setAttributesetAttributeLocal即前者接受 aKey[T <: Number]但将与 key 匹配的值固定为 a Number,而后者更灵活,允许 key 和 value是T <: Number。这看起来很奇怪,您可能需要重新考虑该决定。这也导致了@Ben Schulz 解释的问题。

无论如何,编译器 (2.9.1) 对以下设置感到满意:

MyI.java

public interface MyI {
  public <T extends Number> void setAttribute(Key<T> key, Number value);
}

Key.java

public interface Key<T> {
}

Test.scala

object Test extends App {
  def setAttribute[T <: Number](key: Key[T], value: Number) = {
    setAttributeLocal(key, value)  }

  private def setAttributeLocal[T](key: Key[T], value: Number) = {
    /* Notice that value is now also of type Number. */
  }
}
于 2012-08-02T08:30:04.193 回答