I have the following structure:
public abstract class A <E extends El, U extends A<E,U> > { ... }
public class B<E extends El> extends A<E, B<E> > { ... }
public abstract class C <E extends El, T extends A<E, T>> { ... }
My question is, why can I do this:
public class R extends C<El, B<El>> { ... }
but not
public class R <T extends B<El>> extends C<El, T> { ... }
Why is T (which extends B<El>) not a good substitute for B<El>?
The exception which I get is
Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends A<El,T>> of the type C<E,T>
Try to declare A and C as follows
public abstract class A <E extends El, U extends A<E, ? super U>> {}
public abstract class C <E extends El, T extends A<E, ? super T>> {}
My question is, why can I do this:
public class R extends C<El, B<El>> { ... }
Because El extends El, and B<El> extends A<El, B<El>>
but not
public class R<T extends B<El>> extends C<El, T> { ... }
Because T does not extend A<El, T>. We know that T extends B<El>, and that B<El> extends A<El, B<El>>, and not A<El, T>. This declaration is in general unsafe.
It's impossible to give any suggestions without knowing what you do with these types inside the classes, and why you think the declaration is safe. For example, if it is known that A only serves as a "consumer" of U, then you can use a super bound and it will work:
public abstract class A<E extends El, U extends A<E, ? super U>> { ... }
public abstract class C<E extends El, T extends A<E, ? super T>> { ... }
abstract class A <E extends El, U extends A<E, U> > {
}
class B<E extends El> extends A<E, B<E> > {
}
abstract class C <E extends El, T extends A<E, ? super T>> {
public void X(T t, El a) {
}
}
class R <T extends B<El>> extends C<El, T> {
}
Related
Is it possible to do this in java without problems?
My IDE highlights my code as "Raw use of parameterized class 'Etat' " and "Unchecked call to 'add(E)' as a member of raw type 'java.util.ArrayList'"
My code :
public abstract class Etat<T extends Transition> {}
public abstract class Transition<E extends Etat> {}
Might you be looking for:
class Etat<E extends Etat<E, T>, T extends Transition<E, T>> {}
class Transition<E extends Etat<E, T>, T extends Transition<E, T>> {}
Then, you can do:
class MonEtat extends Etat<MonEtat, MaTransition> {}
class MaTransition extends Transition<MonEtat, MaTransition> {}
allowing the two types to know each other through their type parameter. For instance, if you declare:
class Etat<E extends Etat<E, T>, T extends Transition<E, T>> {
abstract E apply(T transition);
}
You can then be assured that
MonEtat e = ...;
e = e.apply(new MaTransition()); // compiles, and knows that MonEtat is returned
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> {
The following code compiles in jdk6 but not in jdk7. Please suggest any workarounds
public interface LocalCacheMap<K extends Comparable<? super K>, V>
extends ClearableCache<K>, Iterable<V>{
V get(K key);
}
public class Universe<K extends Comparable<? super K>, V, TSKEY extends Comparable<? super TSKEY>> extends MasterLocalCache<K>
implements Iterable<V>, LocalCacheMap<K, V>, TsDaoInfo<TSKEY, K>, ValueConverter<K, Object, V>{
public V get(K key) {
return get(key, keyFunct);
}
abstract public TSKEY buildTsKey(K key, Date date);
abstract public K getObjKey(TSKEY tsKey);
abstract public Date getDateKey(TSKEY tsKey);
}
public class JdbcTimesSeriesCacheDef<K extends Comparable<? super K>, TSKEY extends Comparable<? super TSKEY>, LC extends Universe<K,?,TSKEY>&DataSourceProvider, T> extends AbstractRawTimeSeriesCacheDef<K, T, LC> {
private final SqlDefs<T> defs;
}
When compiling with jdk7, I am getting the following error
JdbcTimesSeriesCacheDef error: get(K#1) in Universe cannot implement get(K#2) in LocalCacheMap
Change
LC extends Universe<K,?,TSKEY>&DataSourceProvider,
to
LC extends Universe<K,T,TSKEY>&DataSourceProvider,
I solved this by using specific Value type 'V' in place of "?"
public class JdbcTimesSeriesCacheDef, V, TSKEY extends Comparable, LC extends Universe&DataSourceProvider, T> extends AbstractRawTimeSeriesCacheDef {
private final SqlDefs defs;
}
I read that using a wildcard with super like this:
public class MyClass <T extends Comparable<? super T>> {
...
}
instead of:
public class MyClass <T extends Comparable<T>> {
...
}
could make the class 'more generic', but I do not understand why.
Can someone provide some concrete examples?
This way you can supply a class for T, which does not for itself implements Comparable, but inherits from a class implementing Comparable.
E.g.
class Baseclass implements Comparable<Baseclass> {
...
}
class Inherited extends Baseclass {
...
}
With a specification like
public class MyClass <T extends Comparable<? super T>> {
...
}
you can use MyClass<Inherited>, and MyClass<Baseclass>, but with
public class MyClass <T extends Comparable<T>> {
...
}
you can only use MyClass<Baseclass>
Can I declare the following in Java?
public class NewIterator<E extends Comparable<? super E>> implements Iterator<E> {
NewIterator(Iterator<? extends E & Comparable<? super E>> iterator){
...
}
I am getting an error saying
Multiple markers at this line
- Incorrect number of arguments for type Iterator<E>; it cannot be parameterized with arguments <? extends E, Comparable<? super E>>
- Syntax error on token ",", ; expected
- Syntax error on token "&", , expected
- Syntax error on token ")", ; expected
By defining your class as
class NewIterator<E extends Comparable<? super E>> implements Iterator<E> {
you say that E has to implement Comparable<? super E>.
Now in the constructor you try to repeat that and allow subtypes of E.
NewIterator(Iterator<? extends E & Comparable<? super E>> iterator){
...
}
If you do just
public NewIterator(Iterator<? extends E> iterator) {
}
You should get what you want because E already defines that it's a type that implements the comparable interface.
Example
class IntegerNumber {}
class PositiveNumber extends IntegerNumber implements Comparable<IntegerNumber> {}
class OddPositiveNumber extends PositiveNumber {}
private NewIterator<PositiveNumber> newIterator;
void foo() {
Iterator<PositiveNumber> iterator = createIteratorFrom(
new PositiveNumber(1),
new OddPositiveNumber(7)
);
this.newIterator = new NewIterator(iterator);
}
If you use PositiveNumber in NewIterator<E extends Comparable<? super E>> you can replace E by PositiveNumber. So your constructor accepts Iterator<? extends PositiveNumber>. You can now create an iterator over any subclass of PositiveNumber but since that class inherits from PositiveNumber it must also inherit the Comparable<IntegerNumber> interface.