Reputation: 1018
There's not much to add to my question, basically:
class A {}
interface I {}
// how can I get a Set<> of object of type A that implements I?
I tried a few things <A & I>
, <A extends I>
, <? super A extends I>
and a few other but didn't find anything that works, so I'm wondering if this is possible at all. If it isn't I'm curious about the reasoning behind it.
Thanks
Upvotes: 1
Views: 396
Reputation: 70564
Java does not support intersection types, it only supports multiple bounds (as in extends A & I
) when declaring type parameters. That is, we can not use a notation like A & I
to denote the family of types that extend both A and I, but we can declare a type parameter <T extends A & I>
to refer to a specific such type.
If the latter is what you want, a type parameter is a great fit. But if your collection should admit unrelated subtypes of A
and I
, no nice solutions seem to exist. My best idea is a hack like:
class AISetWrapper {
Set<A> set = new HashSet<>();
<T extends A & I> Set<T> getSet() {
return (Set<T>) set; // unchecked cast that only works because generics are not reified
}
}
which would allow us to write:
class AI1 extends A implements I { }
class AI2 extends A implements I { }
public static void main(String[] args) {
AISetWrapper aiSet = new AISetWrapper();
aiSet.get().add(new AI1()); // compiles
aiSet.get().add(new AI2()); // compiles
aiSet.get().add(new A()); // does not compile
aiSet.get().add(new I() {}); // does not compile
}
Upvotes: 2
Reputation: 2907
You can write your own class:
public class MySet<E extends A & I> extends HashSet<E> {
// blank
}
This will simply ensure that any instances of MySet
will contain only objects that extend A
and implement I
.
Upvotes: 0
Reputation: 32949
I was able to do the following:
public class MyClass<T extends String & Iterable>{
private Set<T> mySet;
}
And
public <T extends String & Iterable> void myFancyMethod(Set<T> mySet){}
However when I did
private Set<? extends String & Iterable>
I got a compile error of Syntax error on token "&"
. Seems that you can do the &
syntax when declaring a type <T>
but not for wildcards <? ...>
.
A better discussion of this can be found at: Java Generics Wildcarding With Multiple Classes
Upvotes: 1
Reputation: 68915
// how can I get a Set<> of object of type A that implements I?
You cannot guarantee both in a single generic statement. You can do something like
public void addToSet(I iInstance) {
if(iInstance instanceof A){
//logic to add to your set
}
}
Upvotes: -1
Reputation: 31290
You'll have to make A implement I:
interface I {}
class A implements I {}
Set<A> setOfA;
Possible is alsp
class SubA extends A implements I { }
Set <SubA> setOfSubA;
Usage of a class A cannot make it change it's behaviour, as would be indicated by its sudden "implmentation" of I. Where should the implementations of the interface methods come from?
Upvotes: 1