简体   繁体   English

什么是Scala试图告诉我,我该如何解决这个问题? [required:java.util.List [?0] where type?0]

[英]What is Scala trying to tell me and how do I fix this? [ required: java.util.List[?0] where type ?0]

I am in the process of learning Scala and today I felt confident to introduce it to one of our projects. 我正在学习Scala,今天我有信心将它介绍给我们的一个项目。

The application does a lot of JPA / Hibernate stuff and I started implementing one of the Java interfaces in Scala. 该应用程序执行了很多JPA / Hibernate的工作,我开始在Scala中实现一个Java接口。 All went well, until I tried to translate some unittest-code to Scala. 一切顺利,直到我试图将一些单元测试代码翻译成Scala。

I make a lot of use of Easymock, the code is quite self explanatory. 我使用了很多Easymock,代码很自我解释。 I guess the problem is, that Scala does not allow me to return a typed java.util.List where it expects an untyped one. 我想问题是,Scala不允许我返回一个类型化的java.util.List,它需要一个无类型的java.util.List。 Unfortunately I have no idea how to make Scala cast something that expects type parameters to something without. 不幸的是,我不知道如何让Scala转换为需要类型参数的东西。

Code that illustrates/reproduces my problem: 说明/重现我的问题的代码:

package some.package.name

import java.util.ArrayList
import java.util.List
import javax.persistence.Query
import org.easymock.EasyMock._
import org.junit.Assert._
import org.junit.Test

class MyGreatScalaTest {

  @Test
  def testSomething() : Unit = {

    val mockQuery: Query = createMock(classOf[Query])
    val mockResult: List[String] = new ArrayList[String]
    mockResult.add("great value")

    expect(mockQuery.getResultList).andReturn(mockResult)
    replay(mockQuery)

    assertEquals(
      (mockQuery.getResultList.asInstanceOf[List[String]]).get(0),
      "great value")

    verify(mockQuery)
  }
}

Which produces the following compiler error: 这会产生以下编译器错误:

[WARNING]  found   : java.util.List[String]
[WARNING]  required: java.util.List[?0] where type ?0
[WARNING]     expect(mockQuery.getResultList).andReturn(mockResult)
[WARNING]                                               ^     

As you can see I need the mock to implement the interface of javax.persistence.Query , which returns a java.util.List. 如您所见,我需要mock来实现javax.persistence.Query的接口,它返回一个java.util.List。

javax.persistence.Query#getResultList returns a raw type List , as opposed to a *cooked8 type like List[String] . javax.persistence.Query#getResultList返回一个原始类型List ,而不是像List[String]这样的* cooked8类型。 Java generified much of the standard library in version 1.5 but had to be backwards compatible with binaries and sources written for 1.4. Java在1.5版本中标准化了大部分标准库,但必须向后兼容为1.4编写的二进制文件和源代码。

The Scala compiler tolerates such nasty types, but translates it to List[_] , which is shorthand for List[?0] forSome { type ?0 } . Scala编译器容忍这些讨厌的类型,但将其转换为List[_] ,这是List[?0] forSome { type ?0 }简写。 This is known as an existential type, and it means that the element type of the List is some specific type, even though we don't know exactly which one! 这被称为存在类型,它意味着List的元素类型是某种特定类型,即使我们不确切知道哪一个!

Easymock requires that the argument to andReturn is of the same type as the type of the argument passed to expect , our troublesome existential type. Easymock要求andReturn的参数与传递给expect的参数的类型相同,这是我们麻烦的存在类型。

I expect that this will fix the problem: 我希望这可以解决问题:

expect(mockQuery.getResultList.asInstanceOf[List[String]]).andReturn(mockResult)

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

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