来自Scala的Java通配符泛型互操作



我正在用scala编写,我正在处理一个返回a的Java APIList<? extends IResource>,其中IResource是通用父接口(详细信息,如果有帮助的话)。

我试图将IResource添加到该方法返回的列表中,但我无法让我的代码编译(Patient是实现IResource的java类,getContainedResources返回List<? extends IResource>):

这是我的原始代码

val patient = new Patient()
patient.setId(ID)
val patientASResource: IResource = patient
entry.getResource.getContained.getContainedResources.add(patient)

这里是我得到的错误:

type mismatch;
  found   : patientASResource.type (with underlying type ca.uhn.fhir.model.api.IResource)
  required: ?0 where type ?0 <: ca.uhn.fhir.model.api.IResource
         entry.getResource.getContained.getContainedResources.add(patientASResource)
                                                                  ^
 one error found

请注意,我正试图将我键入的patientASResource添加到接口IResource。尝试添加patient(实现接口的类)有更糟糕的错误消息。

我尝试过的其他事情:

//From what I understand of "Java wildcards" per here: http://stackoverflow.com/a/21805492/2741287
type Col = java.util.Collection[_ <: IResource]
val resList: Col = entry.getResource.getContained.getContainedResources
val lst: Col = asJavaCollection(List(patient))
resList.addAll(lst)

也不工作,它返回类似于:

type mismatch
found : java.util.Collection[_$1(in method transformUserBGs)] where type _$1(in method transformUserBGs) <: ca.uhn.fhir.model.api.IResource 
 required: java.util.Collection[_ <: _$1(in type Col)]
 resList.addAll(lst)
 ^

问题不在于互操作性。这绝对不应该编译,同样的Java代码也不应该编译。

List<? extends IResource>意味着它可以是List<IResource>, List<Patient>, List<SomeSubclassOfPatient>, List<SomeOtherResourceUnrelatedToPatient>等,你不知道是哪一个。因此,不允许在这样的列表中添加Patient(或上转换后的IResource)。

如果你知道在你的特定情况下entry是这样的entry.getResource.getContained.getContainedResources返回List[IResource]List[Patient],你应该尝试通过在重写getContainedResources时指定它来静态地确保这一点。如果这是不可能的,最后的办法是强制转换:

entry.getResource.getContained.
  getContainedResources.asInstanceOf[java.util.List[IResource]].add(patient)

重申一下:你应该尽可能避免这种情况。

最新更新