I have a function which maps a class
object to an instance of this class.
Basically:
Function<Class<T>, T> fun;
I can define this function within a method but when trying to put this in a member variable, the compiler complains because the type T
is unknown.
So, T
is not specific to the enclosing object. It might differ from call to call. What is the correct syntax to define such a function on class level?
EDIT
I would like to clarify. I have class A
public class A {
public <T> T get(Class<T> clazz) {...}
}
Now, I want to hand a pointer to that function to class B
like this:
public class B {
<T> Function<Class<T>, T> fun;
public <T> T get(Class<T> clazz) {
return fun.apply(clazz);
}
}
However, the Syntax for <T> Function<Class<T>, T> fun
is incorrect. Is there a way to keep the information, that fun will always retain the type T
?
My current solution is
public class B {
Function<Class<?>, ?> fun;
public <T> void setFun(Function<Class<T>, T> fun) {
this.fun = fun;
}
public <T> T get(Class<T> clazz) {
return (T) fun.apply(clazz);
}
}
This works (and is obviously correct via invariant) but kinda ugly because of the required cast.
In Java (and JVM) values are not polymorphic, methods are.
So correct is to define it with a method
<T> Function<Class<T>, T> fun();
Polymorphic values in Java
Regarding EDIT.
Now, I want to hand a pointer to that function to class
B
like this:public class B { <T> Function<Class<T>, T> fun; public <T> T get(Class<T> clazz) { return fun.apply(clazz); } }
Once again, a value (including a field) can't be polymorphic, method can.
So you can make fun
a method
public abstract class B {
abstract <T> Function<Class<T>, T> fun();
public <T> T get(Class<T> clazz) {
return this.<T>fun().apply(clazz);
}
}
You can't write setter like setFun
. Its signature should be something like
public void setFun(<T> Function<Class<T>, T> fun); // pseudocode
rather than
public <T> void setFun(Function<Class<T>, T> fun);
<T> Function<Class<T>, T>
is called rank-N type and it's absent in Java
What is the purpose of Rank2Types?
https://wiki.haskell.org/Rank-N_types
Alternatively, you can wrap polymorphic fun
with a class (interface)
public interface PolyFunction {
<T> T apply(Class<T> clazz);
}
public class B {
PolyFunction fun;
public void setFun(PolyFunction fun) {
this.fun = fun;
}
public <T> T get(Class<T> clazz) {
return fun.apply(clazz);
}
}
PolyFunction
looks like your A
so maybe you want
public class B {
A a;
public void setA(A a) {
this.a = a;
}
public <T> T get(Class<T> clazz) {
return a.get(clazz);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With