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;
}
Related
class A<T extends Comparable<? super T>> {
Supplier<T> supp;
A(Supplier<T> supp) {
this.supp = supp;
}
static <T extends Comparable<? super T>> A<T> of(Supplier<T> supp) {
return new A<T>(supplier);
}
<U> A<U> map(Function<? super T, ? extends U> mapper) {
return A.of(() -> mapper.apply(this.supp.get()));
}
}
When I compile, I get error saying:
type argument U is not within bounds of type-variable T
where U,T are type-variables:
U extends Object declared in method <U>map(Function<? super T,? extends U>)
T extends Comparable<? super T> declared in class A
I feel that I need to make U in mapper extend something, but I am not really sure how, I have tried U extends Comparable, etc. but they don't work.
Consider the following code:
public final class Algorithm {
public static <T extends Comparable<? super T>>
T max(List<? extends T> list, int begin, int end)
{
// ...
}
}
Is the List<? extends T> list parameter declaration equal to List<? extends Comparable<? super T>> list?
There is a very slight difference.
List<? extends T> means
a List of objects of an unknown type that is either T or a subclsss of T
List<? extends Comparable<? super T>> means
a List of objects of an unknown type that is either Comparable<? super T> or an implementation of Comparable<? super T>.
Let's consider this class hierarchy: A and B are unrelated classes that both implement Comparable<A> and are both final. Yes, I know this situation is contrived.
If, from the return value, T is inferred to be A, you can only pass a List<A> to a parameter of type List<? extends T>. However, you can pass a List<A>, as well a List<B> to a parameter of type List<? extends Comparable<? super T>>.
Here is an example demonstrating my point:
public static void main(String[] args) {
List<A> aList = Collections.singletonList(new A());
List<B> bList = Collections.singletonList(new B());
A a = f(aList);
A b = f(bList); // doesn't compile
A c = g(bList);
A d = g(bList);
}
public static <T extends Comparable<? super T>> T f(List<? extends T> list) {
return null;
}
public static <T extends Comparable<? super T>> T g(List<? extends Comparable<? super T>> list) {
return null;
}
final class A implements Comparable<A> {
#Override
public int compareTo(A o) {
return 0;
}
}
final class B implements Comparable<A> {
#Override
public int compareTo(A o) {
return 0;
}
}
In reality though, very rarely do things like class B implements Comparable<A> happen, so for the most part, the two types in question are the same.
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> {
}
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.
I have a wrapper class for ConcurrentMap like the following:
public MapWrapper<K, V> implements ConcurrentMap<K, V> {
private final ConcurrentMap<K, V> wrappedMap;
...
#Override
public void putAll(Map<? extends K, ? extends V> map) {
wrappedMap.putAll(map); // <--- Gives compilation error
}
...
}
The marked line triggers the following compilation error:
method putAll in interface java.util.Map<K,V> cannot be applied to given types;
required: java.util.Map<? extends capture#5 of ? extends K,? extends capture#6 of ?
extends V>
found: java.util.Map<capture#7 of ? extends K,capture#8 of ? extends V>
reason: actual argument java.util.Map<capture#7 of ? extends K,capture#8 of ? extends V>
cannot be converted to java.util.Map<? extends capture#5 of ? extends K,? extends
capture#6 of ? extends V> by method invocation conversion
I suspect the unbounded wildcards are the culprit but I can't change the method signature since it is inherited from the ConcurrentMap interface. Any ideas?
Have you seen:
What is the difference between bounded wildcard and type parameters?
Let's look to signature of putAll
public void putAll(Map<? extends K, ? extends V> m)
... and to error which you got:
cannot be converted to java.util.Map<? extends capture#5 of ? extends K,? extends
So reason why you can't do it, it's restriction of merging of inheritance tree in Java.
Probably, will be better to write your own implementation of putAll method.
Thanks, hope it will help you.