Reputation: 23
I have generic class ConsumerTest<T, U>
and I plan that T
is mutable type and U
is ekvivalent immutable type like <StringBuilder, String>
, <MutableInt, Integer>
, <MutableDouble, Double>
, ... How can I write generic constructor which creates the mutable type from immutable? Here is my attempt:
import org.apache.commons.lang3.mutable.MutableDouble;
import org.apache.commons.lang3.mutable.MutableInt;
class ConsumerTest<T, U> {
private T value;
public <T, U> ConsumerTest(U u) {
this.value = new T(u); // compile error
}
public static void main(String[] args) {
ConsumerTest ctS = new ConsumerTest<StringBuilder, String>("Hello");
ConsumerTest ctI = new ConsumerTest<MutableInt, Integer>(666);
ConsumerTest ctD = new ConsumerTest<MutableDouble, Double>(11.11);
}
}
Upvotes: 1
Views: 67
Reputation: 178253
As another answer states, new T(u)
is invalid syntax. One cannot use a type parameter as a new class to instantiate, because there is no guarantee that that particular class's constructor takes exactly one argument of that exact type.
In addition, you've created a generic constructor that defines its own T
and U
, which shadow the class's declarations of T
and U
. That's why you get a compiler error message such as "Cannot convert T to T". Remove the declarations of T
and U
from the constructor, but not from the class.
You still need to be able to construct an object of type T
from one of type U
, so provide a converter function. Note here that Java's built in Function
s reverse the sense of U
and T
that you have.
class ConsumerTest<T, U> {
private T value;
public ConsumerTest(U u, Function<U, T> converter) {
this.value = converter.apply(u);
}
public static void main(String[] args) {
ConsumerTest ctS = new ConsumerTest<StringBuilder, String>("Hello", StringBuilder::new);
ConsumerTest ctI = new ConsumerTest<MutableInt, Integer>(666, MutableInt::new);
ConsumerTest ctD = new ConsumerTest<MutableDouble, Double>(11.11, MutableDouble::new);
}
}
There may be additional reasons you need to encapsulate this functionality in a class that you haven't shown, but you may not need a class such as ConsumerTest
. Just create the functions.
Function<String, StringBuilder> ctS = StringBuilder::new;
Or you may not need to bother with the functions at all. Create the mutable objects directly.
StringBuilder sb = new StringBuilder("Hello");
Upvotes: 0
Reputation: 27200
new T(u)
is invalid because T
isn't a type. In order to create an instance of a class, you need to know the type, and you don't in that context.
Upvotes: 2