Can I enforce child classes to create a enum in them?
class Document<T extends Enum<T>>{
Map<T, String> fields;
}
class TextDocument extends Document<TextDocument.Field>{
public enum Field{
...
}
}
How can I enforce any implementation of Document to have an enum named Field within it? In the above example, TextDocument can extend Document with some other enum (say GraphDocument.Field) as well which shouldn't be allowed. How can I create this restriction? I need to enforce this rule to subclasses - "You must have your own enum". Is this even possible? By some hacky way? Any ideas?
In short, you can't. However, you can force it to return an array of the values of a particular enumeration. You can also force the enumeration to implement an interface.
public interface SomeInterface {
// any methods you want to be able to perform on the enums
}
public abstract class SomeSuperClass<T extends SomeInterface> {
abstract T[] getSome();
}
public class SomeSubclass extends SomeSuperClass<SomeInterface> {
public enum SomeEnum implements SomeInterface {
testEnum {
// interface implementation
}
}
public SomeInterface[] getSome() {
return SomeEnum.values();
}
}
This is a pretty awkward solution, but it works.
Related
I defined an interface for enum types.
interface MyInterface<E extends Enum<E> & MyInterface<E>> {
}
// e.g.
enum MyEnum implements MyInterface<MyEnum> {
}
Now I want to access name() method from a method defined in above interface.
interface MyInterface<E extends Enum<E> & MyInterface<E>> {
default void doSomeWithEnumName() {
// How can I access #name() method in here?
}
}
You can cast this to an Enum<?> and just access name().
System.out.println(((Enum<?>) this).name());
However, with the current set up, it is in fact possible for one to be naughty and create a non-enum class that implements your interface:
enum Bar implements MyInterface<Bar> {}
class Foo implements MyInterface<Bar> {}
Therefore, I would advise that you check the type of this first:
if (this instanceof Enum<?> enumThis) {
System.out.println(enumThis.name());
} else {
throw new RuntimeException("Only enums can implement this interface!");
}
(I can't think of how you would limit the interface to be only implementable only for enums - there are no "self" types in Java)
I am following examples in "Effective Java" and came across the following code:
abstract static class Builder<T extends Builder<T>>
and its implementation:
public static class Builder extends Pizza.Builder<Builder>
Why is this declared T extends Builder<T> and not T extends Builder. Is it really needed to add the template <T>? What is the impact if I just use Builder<T extends Builder>?
It is called as "generic type". That declaration means T can be any type that is subclass of Builder<T>.
The goal of implementing Generics is finding bugs in compile-time other than in run-time. Finding bugs in compile-time can save time for debugging java program, because compile-time bugs are much easier to find and fix.
What is the impact if we just use Builder<T extends Builder>?
It transforms into raw type. And type safety goes off.
Builder<T extends Builder<T>> means that,
The class T passed in must implement the Builder interface / extend Builder class, and the generic parameter of Builder must be T itself.
I have some examples to show that actually the difference is not that big. I think the OP wants to know the difference between T extends Builder<T> and T extends Builder.
public abstract class Builder2<T extends Builder2> {
//doesn't compile either, because String is not a subtype of Builder2
static class WrongHouseBuilder extends Builder2<String> {}
//all ok
static class RawHouseBuilder extends Builder2 {}
static class HouseBuilder1 extends Builder2<RawHouseBuilder> {}
static class HouseBuilder2 extends Builder2<HouseBuilder1> {}
static class HouseBuilder3 extends Builder2<HouseBuilder2> {}}
Now with Builder<T>:
public abstract class Builder<T extends Builder<T>> {
//all ok
static class RawCarBuilder extends Builder {}
static class CarBuilder extends Builder<CarBuilder> {}
//ok as well, T doesn't have to be CarBuilder2
static class CarBuilder2 extends Builder<CarBuilder> {}
//doesn't compile because CarBuilder2 is not a subtype of Builder<CarBuilder2>
static class CarBuilder3 extends Builder<CarBuilder2> {}}
Of cause with T extends Builder<T>, you have more protection, but not that much.
UPDATE
Just to clarify, we should not use raw type. #Radiodef has provided an interesting example in the comment. And a quote from that answer to help you understand it:
In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.
Minor: It looks more natural to me to use Builder as an interface, not an abstract class. This is a sort of recursive type declaration. It is used for type safety to prevent nasty things like the following happens:
public abstract Builder<T extends Builder<T>> {
T build();
}
public class Entity extends Builder<String>{ // does not compile
#Override
public String build() {
return null;
}
}
public class Entity extends Builder<Entity>{ //ok
#Override
public Entity build() {
return null;
}
}
Anyway more naturally looking version (from my point of view) is:
public interface Buildable<T extends Buildable<T>> {
T build();
}
public final class Entity implements Buildable<Entity>{
//other methods
#Override
public Entity build() {
//implementation
}
}
I see that the question is about the <T> part in Builder<T>. Without this <T>, you simply get a raw type, and your IDE might complain.
But in my answer, I'd like to explain what's the purpose of T extends Builder<T>, because other answers do not seem to cover it (maybe you know this already).
T extends Builder<T> serves the purpose of returning appropriate Builder.this in all the Builder methods (except build() method, of course).
I usually use it with a protected abstract method like T thisInstance().
Example:
abstract class NamedBuilder<T extends NamedBuilder<T>> {
private String name;
T name(String name) {
this.name = name;
return thisInstance();
}
protected abstract T thisInstance();
}
final class MoreSpecificBuilder extends NamedBuilder<MoreSpecificBuilder> {
#Override
protected MoreSpecificBuilder thisInstance() {
return this;
}
}
Thanks to such approach, you do not have to redefine name() method in all the NamedBuilder subclasses to return the specific subclass.
Without such constraint type parameter T, you would have:
abstract class NamedBuilder {
NamedBuilder name(String name);
}
and you would need to override all such methods in subclasses like that:
final class MoreSpecificBuilder extends NamedBuilder {
#Override
MoreSpecificBuilder name(String name) {
super.name(name);
return this;
}
}
EDIT: Without the constraint extends Builder<T> on type parameter T:
abstract class NamedBuilder<T> {
// ...
}
this would work fine, although such design would be less intuitive and more error-prone.
Without such constraint, compiler would accept anything as T (e.g. String), so the constraint acts simply as a compile-time check for the implementors of NamedBuilder.
I've got generic interface Operand:
public interface Operand<T extends Operand<T>> {
T add(Operand<T> op);
T sub(Operand<T> op);
T mul(Operand<T> op);
T div(Operand<T> op);
}
which is implemented by 2 classes:
public class DoubleOperand implements Operand<DoubleOperand> {
...
}
public class RationalOperand implements Operand<RationalOperand> {
...
}
I've written "factory" interface implemented by DoubleOperandFactory and RationalOperandFactory classes:
public interface OperandFactory {
<T extends Operand<T>> Operand<T> valueOf(String s);
}
public class DoubleOperandFactory implements OperandFactory{
#Override
public Operand<DoubleOperand> valueOf(String s) { ... }
}
public class RationalOperandFactory implements OperandFactory {
#Override
public Operand<RationalOperand> valueOf(String s) { ... }
}
In my program I use an enum which objects store instance of the particular Factory:
public enum OperandType {
DOUBLE(new DoubleOperandFactory()), RATIONAL(new RationalOperandFactory());
private OperandFactory fact;
OperandType(OperandFactory fact){ this.fact = fact; }
public OperandFactory getFact() { return fact; }
}
Now I'm getting message warning "Unchecked overriding" on both factory classes, due to unchecked conversion and I'm pretty confused about this. First thing which I tried is (as it was most commonly answered here in similar topics) to replace generic method with generic factory interface, but finally it turns into impossibility to use them with the enum which should return particular factory, without <?>, as I have to create a List of operands (of generic type T extends Operand<T> for now) and fill it with the objects produced by selected factory. What would be the best way to reorganize this code?
public interface OperandFactory {
<T extends Operand<T>> Operand<T> valueOf(String s);
}
This interface does not do what you think it does.
This interface advertises that an instance of it can generate any type of operand you want. It doesn't just generate one particular kind of operand. It generates all of them.
This is not what you actually have.
What you need instead is
public interface OperandFactory<T extends Operand<T>> {
T valueOf(String s);
}
...and then to give up on the enum, because you can't have enums that have different types in them like that. That's just not a thing you're allowed to do in Java.
Let's say I've got a parent abstract animal trainer class:
public abstract class Trainer
<A extends Animal,
E extends Enum<E> & Trainables>{
protected EnumSet<E> completed;
public void trainingComplete(E trainable){
trainingComplete.add(trainable);
}
I want concrete extensions of the parent animal trainer to complete training for only the trainables defined by it. So if I have a concrete Dog Trainer as follows:
public class DogTrainer extends Trainer<Dog, DogTrainer.Tricks>{
public enum Tricks implements Trainables {
FETCH, GROWL, SIT, HEEL;
}
}
With the current definition of DogTrainer I can only do trainingComplete for parameters of the DogTrainer.Tricks type. But I want to enforce that anyone who creates a concrete Trainer should allow trainingComplete() for Trainables that it defines within itself.
In other words, the problem with my current design is, if I had another trainer as follows:
public class PoliceDogTrainer extends Trainer<Dog, PoliceDogTrainer.Tricks>{
public enum Tricks implements Trainables {
FIND_DRUGS, FIND_BOMB, FIND_BODY;
}
}
There is nothing preventing someone from defining another rouge trainer that tries to teach the dog, police tricks:
public class RougeTrainer extends Trainer<Dog, PoliceDogTrainer.Tricks>{
...
}
I want to prohibit this and allow extending class to use ONLY Trainables they themselves specify.
How can I do that?
You can make the enums non-public but that cannot be enforced by the abstract base class. An alternative is to make Trainables generic by adding a type parameter which must match the Trainer class. This does not enforce the enum to be an inner class (that’s impossible) but for a conforming sub class, no RogueTrainer can be created then.
Enforcing constraints on the type of this inside the base class or interface lies somewhere between tricky and impossible. One commonly known example is the Comparable interface which cannot be declared in a way to prevent implementations like class Foo implements Comparable<String>.
One way to circumvent this problem is to make the Trainer reference a parameter, e.g.
public interface Trainables<T extends Trainer<?,? extends Trainables<T>>>
…
public abstract class Trainer
<A extends Animal,
E extends Enum<E> & Trainables<? extends Trainer<A,E>>> {
protected EnumSet<E> completed;
void trainingCompleteImpl(E trainable) {
completed.add(trainable);
}
public static <A extends Animal, T extends Trainer<A,E>,
E extends Enum<E> & Trainables<T>> void trainingComplete(T t, E trainable) {
t.trainingCompleteImpl(trainable);
}
}
public class PoliceDogTrainer
extends Trainer<Dog, PoliceDogTrainer.Tricks> {
public enum Tricks implements Trainables<PoliceDogTrainer> {
FIND_DRUGS, FIND_BOMB, FIND_BODY;
}
}
The public static method can only be invoked with the right combination of Trainer and Trainables. The trainingCompleteImpl method can be invoked and overridden by trusted subclasses within the same package. If you don’t want this you can inline the code of the method and remove the instance method completely.
_
An alternative is to create a type parameter for the Trainer and enforce a match between the parameter and this at runtime:
public interface Trainables<T extends Trainer<?,T,? extends Trainables<T>>>
…
public abstract class Trainer
<A extends Animal, T extends Trainer<A,T,E>,
E extends Enum<E> & Trainables<T>> {
protected EnumSet<E> completed;
/** sub-classes should implements this as {#code return this}*/
protected abstract T selfReference();
void trainingComplete(E trainable) {
if(selfReference()!=this) throw new IllegalStateException();
completed.add(trainable);
}
}
public class PoliceDogTrainer
extends Trainer<Dog, PoliceDogTrainer, PoliceDogTrainer.Tricks> {
public enum Tricks implements Trainables<PoliceDogTrainer> {
FIND_DRUGS, FIND_BOMB, FIND_BODY;
}
#Override
protected final PoliceDogTrainer selfReference()
{
return this;
}
}
So, for a non-conforming Trainer implementation selfReference() cannot be implemented as return this; which can be detected easily. For a conforming implementation the JVM will inline the selfReference method and see this==this then which will be optimized away; so this check has no performance impact.
I have some problems implementing a Java feature.
I have a list of Sensors. I have different kinds of them, they all extend the base class Sensor.
I have some abstract functions in the base class, and I want these functions to take an Enum as a parameter. The problem is that the Enum is unique for each sub class, and therefore, I can't declare the Enum in the base class.
The code below has Enum as parameter. I know it's not legal syntax, but I just want to illustrate that this is where I want to have the sub class Enum as parameter.
private Vector<Sensor> sensors;
public abstract class Sensor {
public Sensor() {}
public abstract int getParam(Enum param);
public abstract void setParam(Enum param, int value);
}
public class TempSensor extends Sensor {
// Parameter names
public static enum TEMP_PARAMETERS{ PARAM_ALARM_HI, PARAM_ALARM_LO }
public TempSensor() {}
#Override
public int getParam(TEMP_PARAMETERS param) {
// Will do some stuff here
return 0;
}
#Override
public void setParam(TEMP_PARAMETERS param, int value) {
// Will do some stuff here
}
}
If the different Enums implement an interface, I can use the interface as the parameter type in the abstract methods, but then I can pass Enums that don't belong to the respective class as parameter. Is there a way to avoid that?
Looks like you want contradictory things. The whole point of using polymorphism is to take advantage of the substitution principle.
If you want to have a class hierarchy and be sure the right type is entered to the right object, you may consider using the factory pattern.
I strongly recommend against inheritance on Enums; Java doesn't handle that well.
You're on the right track. Assuming you have a marker interface called MyEnumTypeInterface, just have your different enums implement that inferface. Then use MyEnumTypeInterface as the type of the formal parameter for your methods that accept the enum. However, you need to ensure that you're getting an enum that implements MyEnumTypeInterface and not just any other class that implements MyEnumTypeInterface:
public <E extends Enum<E> & MyEnumTypeInterface>void getParam(E e)
This ensures that the formal parameter is an enum and that it implements MyEnumTypeInterface; the methed won't accept as a parameter, another class that also implements MyEnumTypeInterface.
So your classes end up looking like this:
public interface MyEnumTypeInterface {
}
public abstract class Sensor {
public Sensor() {}
public abstract <E extends Enum<E> & MyEnumTypeInterface>int getParam(E param);
public abstract <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value);
}
public enum TempEnum extends MyEnumTypeInterface {
PARAM_ALARM_HI,
PARAM_ALARM_LO
}
public class TempSensor extends Sensor {
public TempSensor() {}
#Override
public<E extends Enum<E> & MyEnumTypeInterface>int getParam(E param) {
return 0;
}
#Override
public <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value) {
// Will do some stuff here
}
}
So you want each Sensor to work a particular param type? That would mean making Sensor generic.
public abstract class Sensor<P extend Enum<P>> {
public Sensor() {}
public abstract int getParam(P param);
public abstract void setParam(P param, int value);
}
There are probably bigger problems with you design. Fixing those could remove the requirement for the get and set.