Reputation: 437
I'm writing in scala and I'm dealing with a Java API which returns a
List<? extends IResource>
, where IResource
is a generic parent interface (the details, if it helps).
I'm trying to add an IResource
to the list returned by that method, but I can't get my code to compile (Patient
is a java class which implements IResource
, and getContainedResources returns the List<? extends IResource>
):
Here is my original code
val patient = new Patient()
patient.setId(ID)
val patientASResource: IResource = patient
entry.getResource.getContained.getContainedResources.add(patient)
And here is the error I get:
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
Notice that I'm trying to add patientASResource
which I've typed-up to the interface IResource
. Trying to add patient
(the class implementing the interface) has a worse error message.
Other things I've tried:
//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)
Doesn't work either, it returns something like:
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)
^
Upvotes: 1
Views: 192
Reputation: 170733
The problem isn't with interop. This definitely shouldn't compile, and neither should the equivalent Java code.
List<? extends IResource>
means it can be a List<IResource>
, List<Patient>
, List<SomeSubclassOfPatient>
, List<SomeOtherResourceUnrelatedToPatient>
, etc. and you don't know which. Thus, adding a Patient
(or an IResource
after upcasting) to such a list is not allowed.
If you somehow know that in your specific situation entry
is such that entry.getResource.getContained.getContainedResources
returns a List[IResource]
, or a List[Patient]
, you should attempt to ensure this statically by specifying this when overriding getContainedResources
. If this is impossible, the last recourse is to cast:
entry.getResource.getContained.
getContainedResources.asInstanceOf[java.util.List[IResource]].add(patient)
Just to reiterate: you should avoid this if at all possible.
Upvotes: 2