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.
Related
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'm new to the art of designing fluent, extensible interfaces. I have a chain of builder classes that implement interfaces and both the interfaces and the builder implementations take self-referential type parameters.
Note: This is related to my previous question in which I had attempted to design the interfaces slightly differently before trying this approach in which the interfaces take a self-referential type parameter as well:
Here is the interface:
public interface ILoadableBuilder<C extends ILoadable,T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>> {
T getState();
B setComponentClass(final Class<C> componentClass);
B setDriver(final WebDriver driver);
B setLoadTimeoutInSeconds(final #Nonnegative int loadTimeoutInSeconds);
B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator);
}
Here is an implementation, which also takes a self-referential type parameter. The reason the class implementation takes the parameter is that I want it to be extensible so that other builders can then extend this class and inherit all its behavior, and that the setters can be called in any order and the return type will be correct:
public class LoadableBuilder<C extends ILoadable,T extends ILoadableBean,B extends ILoadableBuilder<C,T,B>> implements
ILoadableBuilder<C,T,B> {
private final T componentBean;
private IEnumeratorBean<? extends IEnumerable<?>,?> enumerator;
private Class<C> componentClass;
public LoadableBuilder(final T componentBean) {
this.componentBean = componentBean;
}
public final T getState() {
return componentBean;
}
public final B setComponentClass(final Class<C> componentClass) {
this.componentClass = componentClass;
return (B)this;
}
public final B setDriver(final WebDriver driver) {
getState().setDriver(driver);
return (B)this;
}
public final B setLoadTimeoutInSeconds(final int loadTimeoutInSeconds) {
getState().getLoadTimeoutInSeconds();
return (B)this;
}
public B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator) {
this.enumerator = enumerator;
return (B)this;
}
}
My question is, how the heck do you instantiate an instance of this implementation without having to pass a type parameter to the client class? Say, I want to declare a member variable in a class that uses the builder like so:
public ClientClass<C,T> {
private ILoadableBuilder<C,T,_what do I put here????_> builder = new LoadableBuilder<C,T,_what do I put here?????_>();
}
For a method, it's no big deal because I can do this:
public <B extends ILoadableBuilder<C,T,B>> void useABuilder() {
ILoadableBuilder<C,T,B> builder = new LoadableBuilder<C,T,B>();
}
EDIT:
ClientClass would want to build an object that implements the ILoadable interface. I have lots of builders that extend ILoadableBuilder to build objects that implement interfaces which are sub-types of ILoadable. The idea is that I want to be able to get a builder for any object in the inheritance hierarchy underneath ILoadable, which themselves are extensible where necessary.
You have two options:
Make LoadableBuilder not extensible, and just declare it as
public class LoadableBuilder<C extends ILoadable, T extends ILoadableBean>
implements ILoadableBuilder<C,T,LoadableBuilder<C,T>>
If you want to let it be extensible, then make it always necessary to extend it. Let LoadableBuilder be "abstract". Define a bare-bones implementation that just subclasses it with no extra stuff for the "basic" behavior:
public abstract class LoadableBuilder<C extends ILoadable,
T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>>
implements ILoadableBuilder<C,T,B> {
//...
}
public class BasicLoadableBuilder<C extends ILoadable, T extends ILoadableBean>
extends LoadableBuilder<C,T, BasicLoadableBuilder<C,T>> {
}
Suppose I have abstract classes (or, indeed, interfaces)
public abstract class Animal
public abstract class Bird Extends Animal
and a generic class
public class Lifestyle<A extends Animal>
So we might create a Lifestyle<Lion> object.
The Lifestyle class contains methods that animals can use to tell them how to walk around, find food, interact with other animals of the same species, etc. Now suppose I want to extend this class to a special BirdLifestyle class that tells Birds how to do all the above things, but also tells them how to fly and use all of the extra methods in the Bird class. I want to be able to create a BirdLifestyle<Eagle> object, for instance. I'm pretty sure that the following won't compile:
public class BirdLifestyle<B extends Bird> extends Lifestyle<A extends Animal>
and the only alternative I can think of is rather nasty:
public class BirdLifestyle<B extends Bird>
{
private Lifestyle<B> lifestyle // tells the bird how to do animal things.
public Lifestyle<B> getLifestyle()
{
return lifestyle;
}
// Bird-specific methods.
}
We could then get all of the methods from Animal by calling getLifestyle().walk() or things like that.
Now suppose that my friends have all created their own implementations of these four classes and that we want to link them using interfaces. So we create
public interface LifestyleInterface
{
public void walk();
// etc.
}
public interface AvianLifestyleInterface extends LifestyleInterface
{
public void fly();
// etc.
}
My friends are all more specialize, so they've all written things like:
public class LionLifestyle implements LifestyleInterface
or
public class EagleLifestyle implements AvianLifestyleInterface
while I can write:
public class Lifestyle<A extends Animal> implements LifestyleInterface
But I can't now write:
public class BirdLifestyle<B extends Bird> implements AvianLifestyleInterface
even if my BirdLifestyle class overrides all the methods introduced in AvianLifestyleInterface. This is because BirdLifestyle is not a superclass of Lifestyle. The only way round this is to create lots of entry-point methods such as:
public class BirdLifestyle<B extends Bird>
{
private Lifestyle<B> lifestyle;
public Lifestyle<B> getLifestyle()
{
return lifestyle;
}
// 'AvianLifestyleInterface' methods.
#Override
public void fly()
{
// Code for flying.
}
// etc.
// 'LifestyleInterface' methods.
#Override
public void walk()
{
getLifestyle().walk();
}
// etc., creating a similar one-line method for each method in
// 'LifestyleInterface' that is just an entry-point to the same
// method in the 'Lifestyle<A>' object.
}
This seems like an unnecessary amount of code to write, and a lot of the code is written in a fairly mechanical way, which breaks several programming rules. For example, if I want to add any methods to the LifestyleInterface interface then I need to remember to add a new one-line method into the BirdLifestyle class. Is there a cleaner way?
It's a little unclear to me what you are really asking here, but it seems that your first attempt can be easily remedied by:
public class BirdLifestyle<B extends Bird> extends Lifestyle<B> {
// ...
}
Lifestyle is already declared to be generic as Lifestyle<A extends Animal>, no need to repeat what the generic type bound is (and as you say, it won't compile).
Similarly:
public class BirdLifestyle<B extends Bird> extends Lifestyle<B> implements AvianLifestyleInterface {
// ...
}
Will work.
I'm pretty much lost in your question right now. But you can surely change your BirdLifestyle class to:
public class BirdLifestyle extends Lifestyle<Bird> { }
Don't see why you would make BirdLifestyle itself a generic class here. Will update the answer if I understand other part of the question.
If you're moving to interfaces, then you can just do:
public class BirdLifestyle implements AvianLifestyleInterface { }
Again, why would you make the class generic? The name BirdLifeStyle should really describe the life style of a bird. Do you have different kinds of Bird?
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.
I have the following class structure:
public class Team {
...
}
public class Event {
}
public abstract class Fixture<T extends Team> implements Event {
...
}
public abstract class Forecast<Event> {
}
public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{
}
I am trying to model sports events of all kinds (i.e. a 'Fixture' is for a particular game between two participants play against each other, whereas another type of 'Event' may have many participants), along with predictions for the outcome of particular 'Events'. I have a generic method:
public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) {
}
I want to be able to return a MyPrediction instance which has the generic type of the fixture argument, but I can't seem to do so. For example, if I do something like the following, then I get a compilation error:
SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>();
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch);
I am willing to change my class structure to incorporate this feature. How can I do so?
Change the signature of getMyPrediction to
public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture)
This tells the compiler that the fixture types in the argument and result are the same, allowing type-checking to pass.
Here is a complete example, with some other minor changes to get it to compile. It introduces the class Predictor to hold the getMyPrediction method and a doit method to show sample use:
public interface Team {
}
public interface Event {
}
public abstract class Fixture<T extends Team> implements Event {
}
public abstract class Forecast<T> {
}
public class MyPrediction<T extends Fixture<? extends Team>> extends
Forecast<Fixture<? extends Team>> {
}
public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> {
}
public class SoccerTeam implements Team {
}
public class EnglishSoccerTeam extends SoccerTeam {
}
public class Predictor {
public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) {
return new MyPrediction<T>();
}
public void doit() {
SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>();
MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch);
}
}
As noted elsewhere, you might need to introduce one or more factory objects to perform meaningful work in the MyPrediction implementation.
Java's type system is not powerful enough to do directly what you propose, because of type erasure (the generic parameters are not available at runtime.
The usual solution is to create a separate EventFactory class, which you can then pass in to any method which needs to create a specific Event subtype instance.