So, I have a piece of code that goes like
public static void printStuff(Object[] stuffs, Function<?, String> func) {
for(Object stuff : stuffs) {
String stringStuff = func.apply(stuff);
System.out.println(stringStuff);
// or whatever, what is done with that String is not relevant
}
// ...
This method is to be called with arrays of different types, and corresponding func
value, for example:
printStuff(arrayOfClasses, (Class<?> c) -> c.getSimpleName());
printStuff(arrayOfStrings, (String s) -> '"' + s + '"');
printStuff(arrayOfObjects, o -> o.toString());
so I definitely need my stuffs to be Object[]
, because it is the first common superclass of the different types amongst the method's calls.
And on compilation, I get:
MyClass.java:6: error: incompatible types: Object cannot be converted to CAP#1
String stringStuff = func.apply(stuff);
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
My guess is that javac rants for the parameter I give to the Function<?, String>
call, whose type, Object
, does not extend
Object
.
So my question is, how can I pass an Object
parameter to a Function<?, String>
?
I can change the interface types to <Object, String>
, but it breaks my others calls (with Class[]
, String[]
, etc) and it would imply losing pretty much the whole point of genericity, wouldn't it?
Unless there is some way to change my stuffs
type to something like <? extends Object>[]
, or a generic type, and I'm pretty sure it's not possible.
Thanks in advance, folks.
EDIT:if I change my method to a generic one, i.e.:
public static <U> void printStuff(Object[] stuffs, Function<U, String> func) {
I still get a compilation error :
MyClass.java:6: error: method apply in interface Function<T,R> cannot be applied to given types;
String stringStuff = func.apply(stuff);
^
required: U
found: Object
reason: argument mismatch; Object cannot be converted to U
One solution would be to use:
public static <T> void printStuff(T[] stuffs, Function<T, String> func) {
for(T stuff : stuffs) {
// ....