When I create a class with a type parameter:
public abstract class AbstractBox<T> {
abstract T getContent();
}
then I can still create a subclass without a type parameter:
class SomeBox extends AbstractBox { // DISALLOW THIS
@Override
Something getContent() {
return null;
}
}
Can I somehow force subclasses to provide a type parameter (even if it's just Object
)? For instance, I want to disallow the above but allow:
class SomeBox extends AbstractBox<Something> { // ALLOW THIS
@Override
Something getContent() {
return null;
}
}
EDIT: This is not a duplicate of Can overridden methods differ in return type?. That question asks if overriding methods can return subtypes of the type parameter.
My question asks if I can enforce that any subclass of an abstract with a type parameter must provide a type parameter.
You can't force a particular signature of constructor in your subclass - but you can force it to go through a constructor in your abstract class taking two integers. Subclasses could call that constructor from a parameterless constructor, passing in constants, for example. That's the closest you can come though.
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
Multiple BoundsBounded type parameters can be used with methods as well as classes and interfaces. Java Generics supports multiple bounds also, i.e., In this case, A can be an interface or class. If A is class, then B and C should be interfaces. We can't have more than one class in multiple bounds.
Java For Testers Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.
If you want to check if AbstractBox
is provided with a type parameter when extended you can do this:
abstract class AbstractBox<T> {
protected AbstractBox() {
// First, find the direct subclass of AbstractBox
Class<?> cls = getClass();
while(cls.getSuperclass() != AbstractBox.class)
cls = cls.getSuperclass();
// Then, check if it's superclass is parametrized
if (!(cls.getGenericSuperclass() instanceof ParameterizedType)) {
throw new RuntimeException("Must parametrize the extension of AbstractBox.");
}
}
abstract T getContent();
}
Getting the direct subclass first is needed so that it doesn't break in the case where a direct subclass extends AbstractBox
with a parameter, and is then subclassed again.
Note that this will also accept the case of SomBox extends AbstractBox<String>
.
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