I have a class declaration which uses generics and bounded wildcards:
class Factory<T extends Logic<? extends Entity>,
U extends DAO<? extends Entity>>
{
}
Basically its a generic factory, which takes a logic interface (T) and returns a configured implementation. In order to instantiate the logic, I take a appropriate DAO class implementing the DAO interface (U).
Both interfaces for logic and DAO are generic as well and take the type of the entity to work with as their type parameter. However, I want to constrain that further, so that DAO and Logic not only have a type parameter which extends Entity, but that they extend the same Entity. The result may look similiar to that:
class <X extends Entity> Factory<T extends Logic<X>,
U extends DAO<X>>
{
}
Can I achieve that with java generics?
Yes, you're close. Do it like this:
class Factory<X extends Entity,
T extends Logic<X>,
U extends DAO<X>>
{
}
Alternative
class Factory<T extends Logic<?>,
U extends DAO<?>>
{
// Here, the generic method parameter only requires X
// to be the same bound at method invocation. However,
// you will "lose" that information again when the
// Factory is returned.
public static <X extends Entity,
T extends Logic<X>,
U extends DAO<X>> Factory<T, U> createFactory(T logic, U dao)
{
return new Factory<T, U>(logic, dao);
}
}
Another approach could be to provide a wrapper (although that's not really elegant ;) ):
class Entity{}
interface Logic<T extends Entity> {}
interface DAO<T extends Entity> {}
interface DaoLogic<X extends Entity> {
DAO<X> getDAO();
Logic<X> getLogic();
}
class Factory<T extends DaoLogic<? extends Entity>> {}
Would the following work. X would be the "common" type, where Logic and DAO both would use this type.
public class Factory<X extends Entity, T extends Logic<X>, U extends DAO<X>>
{
}
Related
I am new to Java Generics. I have to implement an interface which is of generic type. The syntax is as follows:
public interface A{}
public interface B<T extends A>{
public T methodB(T a) ;
}
Now I have to implement B so Lets say my Class is C
public class C implements B<T extends A>{}
The java compiler is not letting me use it this way. Also I do not want to use raw types. Please help.
It should be
public class C<T extends A> implements B<T>
The type parameter is declared following the class name, and later can be used in the implements clause.
If your implementing class is still a generic type you have to use this syntax:
public class C<T extends A> implements B<T> {}
As explained by Eran.
If C is not generic you simply need to specify the type argument for your interface:
public class C implements B<TypeExtendingA> {}
Where TypeExtendingA implements or extends A (or is A)
I would like to correctly extend an interface but since is uses generics, I became a bit confused.
Here is the first interface
public interface A<T extends Resource>{
...
}
I would like to write something like this but it does not work.
public interface B<T extends Resource> extends A<T extends Resource>
{
...
}
I do not understand why this does not work.
Could you explain?
Since you have already defined the type T, it should be:
public interface B<T extends Resource> extends A<T> {
}
Sorry in advance for any bad english language in this question.
I have in mind to create a sort of factory which can only create instances of classes defined in a list implemented by a concrete factory instance class. First, i defined this interface :
public interface ValuesSystem {
public interface AllowedValue<T extends Class<? extends SystemValue>>{};
AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id);
Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues();
<T extends SystemValue> T create(AllowedValue<Class<T>> allowedClass, ValueData data) throws InvalidValueException;
}
The interface AllowedValue is just a "marker wrapper" interface using generics to define a Class instance "allowed" to be create by my factory.
The getAllowedValue is a method used to get a wrapped allowed Class instance from my allowed Class "list" using an internal enumeration from a concrete class implementing this interface (example of a concrete class will come).
The create method is intended to finally create an instance of my allowed Class instance given in the allowedClass argument.
Here is an example of a concrete class implementing this interface :
public class BasicValueSystem implements ValuesSystem {
public BasicValueSystem() {
super();
allowedValues = (Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>) getAllowedValues();
}
public static enum VALUES_ID {
MODIFIER
}
private static Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowedValues;
private class BasicAllowedValue<T extends Class<? extends SystemValue>>
implements AllowedValue<Class<? extends SystemValue>> {
}
#Override
public <T extends SystemValue> T create(
AllowedValue<Class<T>> allowedClass, ValueData data)
throws InvalidValueException {
if (!(allowedClass instanceof BasicAllowedValue)) {
throw new InvalidValueException();
}
return null;
}
#Override
public AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id) {
return allowedValues.get(id);
}
#Override
public Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues() {
Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowed = new EnumMap<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>(VALUES_ID.class);
allowed.put(VALUES_ID.MODIFIER, new BasicAllowedValue<Class<ModifierValue>>());
return allowed;
}
}
For the moment the create method return null, but the problem is elsewhere and this not the point of my question
The problem occurs when I tried to create an instance of one of my "allowed" values instance with the following code :
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<Class<? extends SystemValue>> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
The compiler tells me :
The method create(ValuesSystem.AllowedValue<Class<T>>, ValueData) in the type BasicValueSystem is not applicable for the arguments (ValuesSystem.AllowedValue<Class<? extends SystemValue>>, ModifierValueData)
I think i missed something concerning the type inference made by generics in general.
Can anyone can explain me the create method signature is not applicable in this case and how to fix it ?
Thanks in advance for taking your time.
Note that public interface AllowedValue<T extends Class<? extends SystemValue>> does not make much sense. The only valid type for T would be Class<? extends SystemValue> as the class Class is final and can’t have subclasses. So you can replace it with interface AllowedValue<Class<? extends SystemValue>> without any change in the semantic, but what you really mean (imho) is interface AllowedValue<T extends SystemValue>. Don’t mess around with Class in a type signature. The interface still might have methods referring to Class<T> then.
public interface ValuesSystem {
public interface AllowedValue<T extends SystemValue>{};
AllowedValue<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create
(AllowedValue<T> allowedClass, ValueData data);
}
Adapt the implementation accordingly, BasicAllowedValue becomes
private class BasicAllowedValue<T extends SystemValue> implements AllowedValue<T>
Then your problem with the using code disappears.
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
will compile.
Note that if AllowedValue shall remain a marker interface without methods only, it is unnecessary, Class<T> already fulfills this role. It will also work when doing it like this:
public interface ValuesSystem {
Class<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create(Class<T> allowedClass, ValueData data);
}
and
BasicValueSystem bvs = new BasicValueSystem();
Class<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
Is this possible?
class A<T extends Service<E extends Entity>>
It's because I want to get the type of Service and Entity. Or any other way around to do it?
Currently I have an abstract method that sets the Service but if I can do it in parameter then much better.
I'm also wondering how can I pass the parameters in a base class:
I have ClassA that extends SubBaseClass1 that extends BaseClass1.
So:
class SubBaseClass1<E extends Entity, P extends Service<E>> { }
In BaseClass, I want to know the type of P and E.
Another question, if I have a method getBaseClass from another class, how will I specify the return type?:
public BaseClass<E extends Entity, T extends Service<E>> getBaseClass() { }
Is not working.
Found the answer:
public BaseClass<? extends IEntity, ? extends Service<?>> getBaseClass() { }
You would declare that like this:
class A<E extends Entity, T extends Service<E>>
Then you could have, for example:
A<Foo, Bar> a;
... where Foo is a subclass of Entity and Bar is a subclass of Service<Foo>.
My main question revolves around when to use and what is the difference between the following when combined with Class, Abstract, Interface:
<E>
<E extends Interface>
<? extends Interface>
Shown below is a detailed question with some code signatures:
This code uses Guava Forwarding Decorators to define specific collections.
Base Interface:
public interface AnimalSetInterface<E extends AnimalI> extends Set<E>
This works:
public interface AsiaI<E extends AnimalI> extends AnimalSetInterface<E>
The following gives an error:
public interface AsiaI<E> extends AnimalSetInterface<E>
Bound mismatch: The type E is not a valid substitute for the bounded
parameter of the type AnimalSetInterface
What I am trying to understand is if I have specified at the Base Interface that I only want <E extends AnimalI> then why do I have to specify again in AsiaI?
I am trying to understand generics and at the same time minimize code.
Also if both classes have such code is there a good way to combine/minimize (remove/generify boilerplate code) it:
Asia:
public Asia(final ImmutableSet<E> animalSet){
super(animalSet);
}
public static <E extends AnimalI> AsiaI<E> of(final ImmutableSet<E> animalSet){
return new Asia(animalSet);
}
Africa:
public Africa(final ImmutableSet<E> animalSet){
super(animalSet);
}
public static <E extends AnimalI> AfricaI<E> of(final ImmutableSet<E> animalSet){
return new Africa(animalSet);
}
public class Africa<E extends AnimalI> extends AnimalSetAbstract implements AfricaI
public class Asia<E> extends AnimalSetAbstract implements AsiaI
The difference is that in the first case, your generic type must extend AnimalI
In the second case, your generic type could be any class.