Is it possible to use wildcards as an attribute itself and not as a type parameter?
public void doSomething(<? extends Context> myObject){
}
I want to make sure that my object extends Context and also implements a certain interface.
Using wildcards as a return type is valid but using it as an attribute seems to not work
public <? extends MyClass> validMethod(){
}
Yes it's possible, you have to define it before the return type.
public <T extends MyClass> void myMethod(T param);
You don't explicitly state (for your case) which is the interface and which is the class, but if you wanted to have a generic type bound to both extending a class and an interface, this would be the general form for it.
public <T extends Number & Comparable<T>> T findNumber(List<T> elements) { }
Number is an abstract class; Comparable is an interface. I believe what you have to specify them in this order - concrete before interface.
Related
The full context being:
public class RClass<T extends Comparable<T>>
Would I be right in saying that the statement in the title means that the arguments plugged into the method must either be an object of a class which implements Comparable OR one of its derived classes?
Thanks.
This means that the type parameter must support comparison with other instances of its own type, via the Comparable interface.
An example of such a class is provided in the Oracle tutorial Object Ordering. Note the similar pattern to T extends Comparable<T> in the excerpt below:
public class Name implements Comparable<Name> {
...
public int compareTo(Name n) { ... }
}
Java- The meaning of <T extends Comparable<T>>?
a) Comparable <T>
is a generic interface (remember it's an "interface" i.e not a "class")
b) extends means inheritance from a class or an interface.
From above-said point#a, it is an interface..(Remember it is an inheritance from an "interface" i.e not from a "class")
c)From above-said both points #a & #b,
here "one interface" extends "another interface".
There should be an interface defined for this class..
just an example here is
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
d) now your class i.e public class RClass {} SHOULD
1# EITHER "implement" this "generic interface" Comparable<T> ..!!!
ex: public class RClass<T> implements Comparable<T>
2# OR create an interface and extend to this "generic interface" Comparable<T>
ex:
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
class RClass<T extends Comparable<T>> implements MinMax<T> {
.....
.....
}
Here,
Pay special attention to the way that the type parameter T is declared by RClass and
then passed to MinMax. Because MinMax requires a type that implements Comparable,
the implementing class (RClass in this case) must specify the same bound. Furthermore,
once this bound has been established, there is no need to specify it again in the implements clause.
Somewhere in that class, the programmer needs to write something like
if(t.compareTo(othert) < 0) {
...
}
For that to work, the type T must have a compareTo-method which compares it to another object of type T. Extending Comparable guarantees the existence of such a method, among other things.
It means that you can only create an instance of RClass with a type which quite literally extends Comparable<T>. Thus,
RClass<Integer> a;
is acceptable, since Integer extends Comparable<Integer>, while
RClass<Object> b;
is not, since Object is not a class which extends comparable at all.
Yes, and bear in mind that objects of classes derived from Comparable ARE Comparable objects. Inheritance is a is-a relationship.
Simply put, the generic type T must be comparable in order to compareTo. otherwise you cannot do T.compareTo.
In Item 28 Effective java, it suggests: "always use Comparable<? super T> in preference to Comparable<T>. <T extends Comparable<? super T>>"
==>guhanvj, <T extends Comparable<T>> means that <T> is having upper bound of Comparable<T> objects. So <T> can have types of Byte, Character, Double, Float, Long, Short, String, and Integer classes which all implements Comparable<T> interface for natural ordering.
I have a method that needs to accept a Enum class. These enums implement an interface. Now I need access to both Enum methods like ordinal(), name(), etc and my interface methods. What I've tried:
public <T extends ConfigFeature, Enum> void showEnabledFeatures(Class<T> enumType, long mask) {
List<T> list = Arrays.asList(enumType.getEnumConstants());
list.forEach(item -> {
// My interface's method, works fine
item.getMask();
// Enum method doesn't work:
// item.ordinal();
});
}
Reversing the order reverses the working:
public <T extends Enum, ConfigFeature> void showEnabledFeatures(Class<T> enumType, long mask) {
List<T> list = Arrays.asList(enumType.getEnumConstants());
list.forEach(item -> {
// My interface's method, doesn't work now
// item.getMask();
// Enum method now works:
item.ordinal();
});
}
Is there a way to get access to both methods from interface and Enum?
You are using the wrong syntax to say that T must implement this interface AND is an enum.
This:
<T extends ConfigFeature, Enum>
is not constraining T to Enum, but actually creating a new generic parameter called Enum.
Similarly,
<T extends Enum, ConfigFeature>
is not constraining T to ConfigFeature. You are declaring a new generic parameter called ConfigFeature.
The correct syntax is to use &:
<T extends Enum<T> & ConfigFeature>
Note that the order is actually important here! Enum can only come first.
According to here, only the first constraint can be a class, and then the ones after it must all be interfaces:
TypeParameter:
{TypeParameterModifier} Identifier [TypeBound]
TypeParameterModifier:
Annotation
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
AdditionalBound:
& InterfaceType
Your syntax is wrong; you need:
public <T extends Enum<T> & ConfigFeature>
That syntax that you used creates two generic type parameters one called T and one called Enum (where Enum isn't bounded and T is bounded to extend ConfigFeature).
Note that, to avoid any generics warnings about the use of raw types, you also have to provide a type parameter to the Enum bound. An enum called X always extends Enum<X>, so you can use T extends Enum<T>, and the full text of the method local generic declaration becomes <T extends Enum<T> & ConfigFeature>
Replace the , in your second example with &. You can use & to declare multiple bounds as long as they’re interfaces from the second type onwards. If you use a comma it’s a separate type parameter, not a bound.
Just to add to existing answers, instead of using Mutliple Bounds as described in other answers, you can define interface that combines interface you want with return method for enum, like:
public interface ConfigFeatureEnumI <T extends Enum<T>> extends ConfigFeatureI{
#SuppressWarnings("unchecked")
default public T asEnum() {
return (T) this;
}
}
You can implement asEnum() in enum used, or just use default method if Java 8 is available as I show here.
public enum ConfigEnum implements ConfigFeatureEnumI<ConfigEnum>{//...
Then showEnabledFeatures can look like:
public <T extends ConfigFeatureEnumI<?>> void showEnabledFeatures(Class<T> enumType, long mask) {
List<T> list = Arrays.asList(enumType.getEnumConstants());
list.forEach(item -> {
// Interface method works:
item.getMask();
// Enum method works via asEnum():
item.asEnum().ordinal();
});
}
While adding new Interfaces is not ideal, it can be easier to use for programmers who do not know Java generics that well or never used Multiple bounds (I use generics a lot, but never needed such feature , so I was a bit off when I did see it).
Consider that I have following interface:
public interface MyInterface<T extends Number>
In another class I want to declare a method like this:
public <T extends MyInterface<?>> void abc(T a);
Is this a correct way? Or maybe should I write:
public <T extends MyInterface<T>> void abc(T a);
What is the difference between these two declarations?
Some interfaces are intended to take the implementing class as the generic type.
For instance, the Comparable interface is usually implemented as:
class MyClass implements Comparable<MyClass>
because then the method
int compareTo(T o);
declared in Comparable can be used to compare an instance of MyClass to another instance of the same class.
Other interfaces have a generic parameter of a different type. For instance, List<T>, where T indicates the type of object contained within the list.
If you declare a method with:
public <T extends MyInterface<T>> void abc(T a);
then you're saying that the class T implements the interface MyInterface in the way that classes implement the Comparable interface - with themselves as the generic type. That might or might not be appropriate depending on what MyInterface actually is.
If you declare a method with:
public <T extends MyInterface<?>> void abc(T a):
then you not placing any constraint on the generic type in T's implementation of MyInterface.
The other option is
public void abc(MyInterface<?> a);
which is the simplest way to write a method that will accept any implementation of MyInterface.
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
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
}
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?
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
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.
// 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
}
}
The full context being:
public class RClass<T extends Comparable<T>>
Would I be right in saying that the statement in the title means that the arguments plugged into the method must either be an object of a class which implements Comparable OR one of its derived classes?
Thanks.
This means that the type parameter must support comparison with other instances of its own type, via the Comparable interface.
An example of such a class is provided in the Oracle tutorial Object Ordering. Note the similar pattern to T extends Comparable<T> in the excerpt below:
public class Name implements Comparable<Name> {
...
public int compareTo(Name n) { ... }
}
Java- The meaning of <T extends Comparable<T>>?
a) Comparable <T>
is a generic interface (remember it's an "interface" i.e not a "class")
b) extends means inheritance from a class or an interface.
From above-said point#a, it is an interface..(Remember it is an inheritance from an "interface" i.e not from a "class")
c)From above-said both points #a & #b,
here "one interface" extends "another interface".
There should be an interface defined for this class..
just an example here is
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
d) now your class i.e public class RClass {} SHOULD
1# EITHER "implement" this "generic interface" Comparable<T> ..!!!
ex: public class RClass<T> implements Comparable<T>
2# OR create an interface and extend to this "generic interface" Comparable<T>
ex:
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
class RClass<T extends Comparable<T>> implements MinMax<T> {
.....
.....
}
Here,
Pay special attention to the way that the type parameter T is declared by RClass and
then passed to MinMax. Because MinMax requires a type that implements Comparable,
the implementing class (RClass in this case) must specify the same bound. Furthermore,
once this bound has been established, there is no need to specify it again in the implements clause.
Somewhere in that class, the programmer needs to write something like
if(t.compareTo(othert) < 0) {
...
}
For that to work, the type T must have a compareTo-method which compares it to another object of type T. Extending Comparable guarantees the existence of such a method, among other things.
It means that you can only create an instance of RClass with a type which quite literally extends Comparable<T>. Thus,
RClass<Integer> a;
is acceptable, since Integer extends Comparable<Integer>, while
RClass<Object> b;
is not, since Object is not a class which extends comparable at all.
Yes, and bear in mind that objects of classes derived from Comparable ARE Comparable objects. Inheritance is a is-a relationship.
Simply put, the generic type T must be comparable in order to compareTo. otherwise you cannot do T.compareTo.
In Item 28 Effective java, it suggests: "always use Comparable<? super T> in preference to Comparable<T>. <T extends Comparable<? super T>>"
==>guhanvj, <T extends Comparable<T>> means that <T> is having upper bound of Comparable<T> objects. So <T> can have types of Byte, Character, Double, Float, Long, Short, String, and Integer classes which all implements Comparable<T> interface for natural ordering.