After one day searching I decided to ask your helps guys :-)
here is my issue:
I need to write coverter for some pojos.
public abstract class Answer<T extends Serializable> implements Serializable {//some code}
public class BooleanAnswer extends Answer<Boolean> {//some code}
public abstract class AnswerDMO<T extends Serializable> implements Serializable {//some code}
public class BooleanAnswerDMO extends AnswerDMO<Boolean> {//some code}
public interface Converter<I, O> {
O convert(I input);
}
public abstract class AnswerConverter<A extends Answer<Serializable>, J extends AnswerDMO<Serializable>>
implements Converter<A, J>, Serializable {
#Override
public J convert(A input) {
// some code
}
}
public class BooleanAnswerConverter extends AnswerConverter<BooleanAnswer, BooleanAnswerDMO>
{
#Override
public BooleanAnswerDMO convert(BooleanAnswer input) {
// some code
}
}
I'm getting an error on the BooleanAnswerConverter, the parameter BooleanAnswer is not within its bound, should extend Answer
I tried many combination but couldnt get it right.
How to fix it?
Since A and J extends Answer and AnswerDMO, and they have the type, you must change the AnswerConverter from:
public abstract class AnswerConverter<A extends Answer<Serializable>, J extends AnswerDMO<Serializable>>
To:
public abstract class AnswerConverter<A extends Answer, J extends AnswerDMO>
Answer and AnswerDMO has the type that is forcing the Serializable. Boolean in you example. Answer<Serializable> will try to ensure that the final implementation is this one, not a generic Answer.
This change result in correct compile of class:
public class BooleanAnswerConverter extends AnswerConverter<BooleanAnswer, BooleanAnswerDMO> {
#Override
public BooleanAnswerDMO convert(BooleanAnswer input) {
return null;
}
}
I don't know if this is what you want but a working solution would be
abstract class AnswerConverter<A extends Answer<? extends Serializable>,
J extends AnswerDMO<? extends Serializable>> implements Converter<A, J>, Serializable {
Related
These are some of the classes that I'm using
public abstract class DCDataManager<T extends DCData> {
public T getData(UUID id){
return cache.get(id);
}
...
public class ApfelPlayerDataManager extends DCPlayerDataManager<ApfelPlayerData>{
public ApfelPlayerDataManager(DrycellPlugin plugin) {
super(plugin);
this.type = ApfelPlayerData.class;
this.loadCurrentPlayers();
}
....
Based on the above classes, why do I need to cast apfelPlayerDataManager.getData(p.getUniqueId()) to ApfelPlayerData? Shouldn't it always return an ApfelPlayerData instance?
ApfelPlayerDataManager apfelPlayerDataManager = new ApfelPlayerDataManager(this);
ApfelPlayerData data = apfelPlayerDataManager.getData(p.getUniqueId());
Nevermind, found the problem. Thanks Bohemian, the last reply led me to look in the right direction.
Basically I had 3 classes:
public class DCDataManager<T extends DCData>
public class DCPlayerDataManager<T> extends DCDataManager
public class ApfelPlayerDataManager extends DCPlayerDataManager<ApfelPlayerData>
The problem stemmed from the second class' definition. This worked:
public class DCDataManager<T extends DCData>
public class DCPlayerDataManager<T extends DCData> extends DCDataManager<T>
public class ApfelPlayerDataManager extends DCPlayerDataManager<ApfelPlayerData>
I have an interface
public interface TransferObjectUtil<B extends BusinessObject,T> {
public T to(B domain);
public B from(T transferObject);
}
I am implementing the class for this as
public class ReflectionBasedTransferObjectUtil<B extends BusinessObject, T> implements
**TransferObjectUtil<B extends BusinessObject, T>** {
For the portion within the ** in the above line the compiler complains that for B extends BusinessObject is not allowed. Why would it be so ?
I am just starting with generics, so pardon me for my novice question.
Your location for the generics is a bit wrong / overeager, try it like this
public class ReflectionBasedTransferObjectUtil<B extends BusinessObject, T> implements TransferObjectUtil<B, T> {
I have created following classes using generics
public interface FacilityMasterService extends AbstractAssessmentLevelService<E extends AbstractAssessmentLevelBean> {
}
public interface AbstractAssessmentLevelService extends AbstractAssessmentService<E extends AbstractAssessmentBean> {}
public interface AbstractAssessmentService extends GenericService<E extends GenericBean> {}
public interface GenericService<E> {}
public class AbstractAssessmentLevelBean extends AbstractAssessmentBean {
}
public class AbstractAssessmentBean extends GenericBean {
}
public class GenericBean{
}
But in interfaces I am getting following error Syntax error on token "extends", , expected
how to resolve this.
please help.
This is not valid:
... extends AbstractAssessmentLevelService<E extends AbstractAssessmentLevelBean>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(You can't extend a class without specifying a concrete type argument.)
Perhaps you're after this:
public interface FacilityMasterService<E extends AbstractAssessmentLevelBean>
extends AbstractAssessmentLevelService<E> {
}
I have the following code, which ended up this way due to other constraints:
public interface Action { }
public interface Result { }
public interface Player<A extends Action, R extends Result, P extends Player<A, R, P>> { }
public interface Game<A extends Action, R extends Result, P extends Player<A, R, P>> { }
abstract public class AbstractGame<A extends Action, R extends Result, P extends Player<A, R, P>> implements Game<A, R, P> { }
public class RPSGame<P extends RPSPlayer<P>> extends AbstractGame<RPSGesture, RPSResult, P> { }
Other relevant classes/interfaces:
abstract public class GesturePlayer<A extends Action, R extends Result, P extends GesturePlayer<A, R, P>> implements Player<A, R, P> { }
abstract public class RPSPlayer<P extends RPSPlayer<P>> extends GesturePlayer<RPSGesture, RPSResult, P> { }
public class RPSHumanPlayer extends RPSPlayer<RPSHumanPlayer> { }
public class RPSSimpleAIPlayer extends RPSPlayer<RPSSimpleAIPlayer> { }
public enum RPSGesture implements Gesture, Action, GestureFPSRules { }
public enum RPSResult implements Result { }
Then I noticed that, due to all changes, I am using raw types in my program, which I do not want at all:
private void init() {
RPSGame rpsGame = new RPSGame();
rpsGame.addPlayer(new RPSHumanPlayer());
rpsGame.addPlayer(new RPSSimpleAIPlayer());
rpsGame.playGame();
}
Here RPSGame is a raw type, while I initially intended it to be raw, it got generics added to it to keep the code working.
The problem is that I cannot make it non-generic as then the code does not compile anymore with everything that I have tried, therefore is it possible to:
Either remove the generics from the RPSGame class?
Or define RPSGame rpsGame in such a way (with typed parameters), that it compiles?
Let's say I have these two inheritance hierarchies:
class EntityA { ... }
class EntityB extends EntityA { ... }
class EntityAPrime extends AbstractPrime<EntityA> { ... }
class EntityBPrime extends EntityAPrime { ... }
I'd also like covariant return types:
public class EntityA {
public EntityAPrime prime() {
return new EntityAPrime();
}
}
public class EntityB extends EntityA {
#Override
public EntityBPrime prime() {
return new EntityBPrime();
}
}
So far so good.
The problem is I'd like EntityBPrime to ultimately extend AbstractPrime<EntityB> but since it extends EntityAPrime it ultimately extends AbstractPrime<EntityA>.
I can make EntityAPrime and EntityBPrime generic, but then I lose covariant return types:
public class EntityA {
public EntityAPrime<EntityA> prime() {
return new EntityAPrime();
}
}
public class EntityB extends EntityA {
#Override
public EntityBPrime<B> prime() { // ERROR: EntityBPrime extends EntityAPrime
return new EntityBPrime(); // but can't substitute <EntityB> for <EntityA>
}
}
Everything works if I return a bound wildcard but there's disadvantages associated with that and I wouldn't be able to call a particular setter on AbstractPrime.
Another idea I had is to make EntityA and EntityB themselves generic.
public class EntityA<T extends EntityA> {
public EntityAPrime<T> prime() { ... }
}
public class EntityB<T extends EntityB> extends EntityA<T> {
#Override
public EntityBPrime<T> prime() { ... }
}
This should work but I think it will get messy (we have over 100 entities that would use a similar pattern).
So, is there any way to:
keep covariant returns
not use generics on EntityA and EntityB
not have prime() return a bound wildcard
and have EntityBPrime ultimately extend AbstractPrime<EntityB> instead of AbstractPrime<EntityA>
Note: the prime classes are generated code, but I have control over the code that does the generating.
First, it's slightly confusing that both your interfaces and classes are called A and B. So, I've renamed the classes as AImpl and BImpl respectively. Also, your classes APrime and BPrime are not typed (they need to be), so I've assumed they are typed on <T extends A> and <T extends B> respectively (if I've misunderstood your intentions/objectives/requirements, I apologise).
private interface A {}
private interface B extends A {}
private abstract class AbstractPrime<T extends A>{}
private class APrime<T extends A> extends AbstractPrime<T>{}
private class BPrime<T extends B> extends APrime<T>{}
private class AImpl {...}
private class BImpl {...}
My first instinct was, as you had considered, to type the implementations on the interfaces. This would work:
private class AImpl<T extends A> {
public APrime<T> prime(){
return new APrime<>();
}
}
private class BImpl<T extends B> extends AImpl<T> {
public BPrime<T> prime(){
return new BPrime<>();
}
}
However, if you have typed APrime on <T extends A> and BPrime on <T extends B>, do you need the return type of prime() to be typed? Might the following solution work for you?
class APrime<T extends A> extends AbstractPrime<T>{}
class BPrime<T extends B> extends APrime<T>{}
public class AImpl {
public APrime prime(){
return new APrime<>();
}
}
public class BImpl extends AImpl {
public BPrime prime(){
return new BPrime<>();
}
}
I guess the answer to that is somewhat whether you envision needing the following:
private interface C extends B {}
public void main(String[] args) {
BPrime<C> prime = new BImpl<C>().prime(); // do you need this?
BPrime<B> prime = new BImpl<>().prime(); // do you need this?
BPrime prime = new BImpl().prime(); or is this sufficient...?
}
As I have mentioned in the comment, there are lots of places that type params are omitted, which makes the whole story doesn't look right.
First, your Primes should at least looks like:
class EntityAPrime<T extends EntityA> extends AbstractPrime<T> {}
class EntityBPrime<T extends EntityB> extends EntityAPrime<T> {}
Then the question comes to your entity
class EntityA {
public EntityAPrime<????> prime(); <- What should be the reasonable type param here?
}
class EntityB extends EntityA {
public EntityBPrime<????> prime(); <- Same here
}
The answer is dependent on your design.
I don't see how your second choice is messier than your original one (given the original one is REAL messy)
You may consider this (Not tested, and whether or not it is right greatly depending on your design, but at least type params looks reasonable to me):
public class Entity<T> {
public Prime<T> prime();
}
public class AbstractEntityA<T extends EntityA> extends Entity<T> {
#Override
public AbstractAPrime<T> prime();
}
public class EntityA extends AbstractEntityA<EntityA>{
public EntityAPrime prime() { ... }
}
public class EntityB extends AbstractEntityA<EntityB> {
public EntityBPrime prime() {...}
}
public class AbstractAPrime<T extends EntityA> extends AbstractPrime<T> {}
public class EntityAPrime extends AbstractAPrime<EntityA>{}
public class EntityBPrime extends AbstractAPrime<EntityB>{}
In brief, move content in your original EntityA to an abstract class, for which to be extended by EntityA (mostly just a plain extends) and EntityB (overriding and adding more things). Same applies to Prime.