I have an interface called Bar
and a generic class Foo
parameterized on a type that is a Bar
:
class Foo<B extends Bar> { }
My class has a general purpose constructor that takes a Class
and a Stream
:
class Foo<B extends Bar> {
B[] bs;
Foo(Class<B> clazz, Stream<B> stream) { // General ctor
bs = someFunctionOf(clazz, stream);
}
}
I'm trying to add a specialized constructor which is requires that its actual method parameter both is a Bar
and an enum
class such that I can call my general purpose constructor from the special constructor:
class Foo<B extends Bar> {
B[] bs;
Foo(Class<B> clazz, Stream<B> stream) { // General ctor
bs = someFunctionOf(clazz, stream);
}
// FIX THIS ----+
// |
// ˅
Foo(Class<Something> clazz) { // Special ctor
// Can we make this work so Something is a Bar and an enum
// and we can call the other constructor like this?
this(clazz, Arrays.stream(clazz.getEnumConstants());
}
}
Generally speaking, you can write generic constructors. We recently had a question about them, and how they might be useful. In this way, you could provide a constructor that takes as an argument a Class representing a class that both extends some specific other class and implements interface Bar
:
class Foo<B extends Bar> {
B[] bs;
Foo(Class<B> clazz, Stream<B> stream) { // General ctor
bs = someFunctionOf(clazz, stream);
}
private B[] someFunctionOf(Class<B> clazz, Stream<B> stream) {
return null;
}
<T extends SomeClass & Bar> Foo(Class<T> clazz) {
// ...
}
}
But that does not quite get you where you want to be, because the bounds of the constructor's type argument T
need to be explicit types. Type variables such as the class's type parameter B
do not serve, and without a way to connect T
to B
, the special generic constructor cannot invoke the general constructor.
But you can do this with a factory method instead of a special constructor:
class Foo<B extends Bar> {
B[] bs;
Foo(Class<B> clazz, Stream<B> stream) { // General ctor
bs = someFunctionOf(clazz, stream);
}
private B[] someFunctionOf(Class<B> clazz, Stream<B> stream) {
return null;
}
static <T extends Enum<T> & Bar> Foo<T> createEnumFoo(Class<T> clazz) {
return new Foo<>(clazz, Arrays.stream(clazz.getEnumConstants()));
}
}
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