Sonar says
Generic wildcard types should not be used in return types
Now I have to use an API that accepts an Iterable<SomeType<?>>
as parameter. How should I create this parameter without violating the Sonar rule if I want to create it in a separate method - so not inline like List<SomeType<?>> param = new ArrayList();
Some code I've played around with:
interface X<T> {
}
static class Blarp {
void addSomeBlarps(Iterable<X<?>> blub) {
}
}
@Test
void testGenerics() {
Blarp b = new Blarp();
X<?> c = new X<>() {};
X d = new X() {};
List<X> blarpList = new ArrayList();
blarpList.add(c);
blarpList.add(d);
List<X<?>> blubList = new ArrayList<>();
blubList.add(c);
blubList.add(d);
// blubList.addAll(blarpList); does not work - why? why can a single X be added but not multiple?
// blubList.addAll((Collection<? extends X<?>>) blarpList); does seem to work with IntelliJ but then fails on compile
// b.addSomeBlarps(blarpList); doesn't work - why?
b.addSomeBlarps(blubList);
}
CodePudding user response:
Probably there's a misunderstanding.
Let's have a look at
public void someMethod(SomeType<?> param) { ... }
This method accepts a parameter param
which has to be of the parameterized type SomeType
but the method doesn't mind the type parameter (put casually). That is, you can call this method with any parameter of type SomeType
regardless of the used type parameter.
So, you can create your objects with a concrete type parameter and hand it over to the method, for example
public class Test<T> {
public static void main(String[] args) {
print(newTestString());
print(newTestLong());
}
public static void print(Test<?> someTest) {
System.out.println(someTest);
}
public static Test<String> newTestString() {
return new Test<String>();
}
public static Test<Long> newTestLong() {
return new Test<Long>();
}
}
Update
The misunderstanding was at my side as it's about a generic type of a generic type. That's a different story. In the example the type is an Iterable which is parameterized by SomeType<?>
. The problem is, that Iterable<SomeType<String>>
is not a subtype of Iterable<SomeType<?>>
.
The method would have to accept e. g. a parameter of type Iterable<? extends SomeType<?>>
to be able to pass a Iterable<SomeType<String>>
.
As the method is given the way it is, you'll have to work around.
(EDIT: deleted crap I wrote)
I would either not factor out the creation of the object or suppress the warning in that case.