This code has an error in it but I dont know how I can go about correcting it:
public class Point<T extends Number super Integer>{
}
Super is only valid with wildcards, not with named type parameters.
Let's imagine the compiler allowed that. There are only two types that can be said to extend Number and be a supertype of Integer, those are Number and Integer.
I'm struggling to see what benefit you would get in doing this rather than a straightforward non-generic Point type with int fields.
If the real case is more involved and you want a generic Point that could use Doubles, Integers etc., sure, use T extends Number if the Number restriction helps to avoid mistakes.
However, just having T extends Number does not give you access to +, -, *, etc. You might want the type class pattern for that, which involves having a separate dictionary of operations passed from the point where the generic type is created to where the numeric operations happen.
E.g.,
interface NumericOperations<T extends Number> {
T plus(T x, T y);
T subtract(T x, T y);
T multiply(T x, T y);
...
}
You would need to define instances of that type class, e.g., public static final NumericOperations intOperations = new NumericOper.....;
..and pass those instances around to get at plus, minus etc., within Point's methods.
public class Point<T extends Number>{
}
or this
public class Point<T extends Integer>{
}
You can't use super like that. See here: java generics super keyword
You can only use the super keyword with a wildcard.
You should take a look at the PECS principle : Provider Extends Consumer Super.
The super keyword is used in generics methods for consumer generic objects.
Example :
public void copyList(List<? extends Number> elementsToBeCopied,
List<? super Integer> listToBeFilled) {...}
Remark : Integer is a final class and cannot be extended, so the extends keyword is unnapplicable.
This article shows a good example of how super and extends can be used.
Related
Sorry guys, this might be a naive question.
I am a little bit confused by bounded type parameter and wildcard. What's the difference between <T extends String> and <? extends String>?
Thanks
I think you are mixing up some things here.
<T extends String> is used when you declare a generic class.
<? extends String> is used on instances from classes that are already generic.
Let’s take the interface “List” from the collections framework for example:
List <E> is the same like List <E extends Object> meaning that you can use the list with every datatype that inherits from Object.
The wildcard <?> can only be used on Classes that are already generic. Taking the example from above with List<E>.Let’s say you have a method that is using the List, but you don’t want to allow every datatype that inherits from Object.
You could use a distinct datatype like:
public void myMethod(List<String> list){
//…
}
But you could also use a range of datatypes that you want to allow:
public void myMethod(List<? extends String> list{
//..
}
In the second example you could use every datatype that is covariant with string i.e. is a child of string.
Tldr:
Bounds <T extends String> are used to declare the range of datatypes a generic class is supporting.
Wildcards <? extends String> are used on classes that are already generic and restrict/limit the given datatypes to a certain range.
The second one basically means: you really don't care about the actual type. You just care that it would extend String.
In other words: if your code does not need to use "T" anywhere; then you can make your intention more clear by "not at all mentioning that type name T".
For more technical background, one of the best resources is the work of Angelika Langer.
Suppose I have a class
public static class A<T extends D> { ... }
and the class D with two classes extending it: B and C, e.g.
public static class D { ... }
public static class B extends D { ... }
public static class C extends D { ... }
Now, at some place let's say I want an array of A's, irrespective of being of the B-kind or the C-kind. (And apply functions from class D to all items in the array, for example.)
Should I then constrain the type again?
In other words: which of these options is the one to go with?
A<?>[] re;
A<? extends D>[] re;
Which one is best practice?
Since T has an upper bound of D, A<?> is just a shorthand for A<? extends D>. They both mean the same thing - just like if T were unbounded, A<?> would be short for A<? extends Object>.
I don't know of any best practice when it comes to this syntax; I think it's just a matter of coding style. I would prefer A<?> because it's concise, though A<? extends D> immediately communicates the upper bound to a developer unfamiliar with A.
According to me you should go with A<? extends D>[] re;
So that user will not allow you to add only object which extends class D
bounded wildcards provides limited flexibility within bound. Any Type with bounded wildcards can only be instantiated within bound and any instantiation outside bound will result in compiler error.One of the important benefit of using bounded wildcard is that it not only restrict number of Type can be passed to any method as argument it also provides access to methods declared by bound. for example TreeMap(Comparator<? super K> comparator) allows access to compare() method of Comparator in Java.
I'm writing a generic function in java, however, I can't seem to tell if there's any way of setting a list of classes that a Generic Object must be in.
Something like this:
public static <T in {String.class, Integer.class, Long.class}> Collection<T> test(Collection<T> val);
You can have Bounded Type Parameters like this for example:
public static <T extends String & Runnable> Collection<T> test(Collection<T> val);
But your example will not work since you have several classes and Java does not support Multiple inheritance.
Also, your examples String, Integer and Long are final so they will not possible to extend anyway.
No. You can't do that in java.
What you desire is an "OR" bound. Java allows "AND" bounding, eg:
List<T extends Runnable & Comparable<T>>
But the analogous "OR" is not supported:
List<T extends Integer | String> // doesn't compile
When you think about it, it doesn't make any sense. Use separate classes/methods for each type bound.
Unfortunately you can't do what you're trying to do in Java - if it allowed you to specify a generic from a list, you'd be able to write a function which operated either on Integers or ArrayLists, which makes no sense as they don't share common functionality. If you want to limit your method to certain types, either find a base class/interface which they all inherit from supporting the functionality you need (public static <T extends BaseClass> Collection<T> test(Collection<T> val);) or write a set of oveloaded methods, one for each type you want to support.
Well you can and can not at the same time.
In your specific example it is impossible.
But such an example would work:
public <T extends CharSequence & Comparable & Closeable> void go(){
For your case I would go with:
public <T extends Number & CharSequence> void go() // same rule applies as extend a class and implement as many interfaces as you want
You cannot do that. Generics is only for enforcing type safety (guaranteeing that the type can perform a particular method, etc.). There is no type-safety requirement that correspond to such an "OR" bound. Requirements on type safety only require an "AND" bound.
I am a little confused with something.
I have a class where its not a collection, but it does refer to generic objects:
public class XClass<E extends AnInterface>{
E instanceobject;
public void add(E toAdd){}
}
public interface AnInterface{}
public class A implements AnInterface{}
public class B implements AnInterface{}
I believe I read somewhere that <? extends AnInterface> is to be used (when declaring an instance of XClass) if you want multiple subtype-types in the generic object at the same time, whereas <T extends AnInterface> would only allow you to have a single type of subtype in the generic class at once?
However, I can just use:
XClass<AnInterface> xc = new XClass<AnInterface>();
A a = new A();
B b = new B();
xc.add(a);
xc.add(b);
and this way I can pass in multiple subtypes of Supertype to the generic class......
I am not seeing the purpose of using "?" and is there anything wrong with using the Interface as the generic parameter?
The reason why you can add objects of both type A and B is due to the fact that you parametized your XClass with the interface, so there is nothing wrong with adding two different classes that implement that interface.
If, on the other hand, you had defined XClass as:
XClass<A> xc = new XClass<A>();
then the expression xc.add(b); would give a compilation error, since all the objects added must have the same type as was declared, in this case, A.
If you declare you xc as, for instance:
XClass<? extends AnInterface> xc = new XClass<AnInterface>();
Then it's not legal anymore to add a or b, since the only thing we know is that xc is of some unknown but fixed subtype of AnInterface, and there is no way to know if that unknown type is A or B or anything else.
But let's say you're writing a method to accept a XClass type that you can iterate over the elements that were added before. Your only restriction (for the sake of the example), is that the items extend AnInterface, you don't care what the actual type is.
You can declare this method like:
public static void dummyMethod(XClass<? extends AnInterface> dummy){
//do stuff here, all the elements extend (implement in this case), AnInterface, go wild.
}
And now you can pass into this method anything like XClass<A>, XClass<B> or XClass<AnInterface>, and it will all be valid.
Keep in mind that you can't add to the object you pass, for the same reason above. We don't know what the unknown type is!
public static void dummyMethod(XClass<? extends AnInterface> dummy){
//do stuff here, all the elements extend (implement in this case), AnInterface, go wild.
dummy.add(new A()); //you can't do this, we have no idea what type ? stand for in this case
}
You can use E if you want to have an instance of XClass to use only one subclass of AnInterface and no other Classes implementing AnInterface that do not extend / implement E.
For example given
public class ClassOne implements AnInterface {} and public class ClassTwo implements AnInterface {}
If you were to use
public class XClass<E extends AnInterface> and <ClassOne>XClass xc = new <ClassOne>XClass() then you can only use an object of ClassOne in your add method not one of ClassTwo. Using ? would allow you to pass in any class implementing AnInterface, either ClassOne or ClassTwo.
Using Identifier E means "For this object I want to use type E and any subclasses", using ? means "I want to use any type that matches the the expression"
In your example you need type erasure in the method "add", so you should't use wildcards in your class.
Wildcards are only to be used when you do not need type erasure (i.e. you don't care about the type as long as it is a subclass of..) and also when you will need to subtype the generics itself.
The wildcard simply means that it will be some class that meets that criteria. So ? extends AnInterface means it will be one (and only one) class that extends AnInterface.
So it could be:
XClass<Impl1>
XClass<Impl2>
etc...
However, at runtime, you don't know what that class will be. For this reason calling methods which take the actual type as a parameter is inherently unsafe, since it's impossible for the compiler to know if the parameter is appropriate for the actual instantiated instance.
Take lists as an example. Something might be declared like this:
List<? extends Number> list = new ArrayList<Integer>();
What would happen if you try to do either of these:
list.add(new Double(0));
list.add((Number) new Long(1L));
It would not compile, because the generic parameter type is unknown at compile time. So the compiler can't tell if Double or Number would be appropriate to pass to the actual instance (in this case ArrayList<Integer>). This is when you get the infamous capture-of compile error.
This, however is permissible, since you know for certain at compile time that the list can take any instance of Number (which includes subclasses).
List<Number> list = new ArrayList<Number>();
list.add(new Double(0));
list.add((Number) new Long(1L));
In Java, covariance allows the API designer to specify that an instance may be generalised as a certain type or any of that type's subtypes. For example:
List<? extends Shape> shapes = new ArrayList<Circle>();
// where type Circle extends Shape
Contravariance goes the other way. It allows us to specify that an instance may be generalised as a certain type or supertype.
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry
How is Java generic's contravariance useful? When would you choose to use it?
Here's a relevant excerpt from Java Generics and Collections:
2.4. The Get and Put Principle
It may be good practice to insert wildcards whenever possible, but how do you decide
which wildcard to use? Where should you use extends, where should you use super,
and where is it inappropriate to use a wildcard at all?
Fortunately, a simple principle determines which is appropriate.
The Get and Put Principle: use an
extends wildcard when you only get
values out of a structure, use a super
wildcard when you only put values into
a structure, and don't use a wildcard
when you both get and put.
We already saw this principle at work in the signature of the copy method:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
The method gets values out of the source src, so it is declared with an extends wildcard,
and it puts values into the destination dst, so it is declared with a super wildcard.
Whenever you use an iterator, you get values out of a structure, so use an extends
wildcard. Here is a method that takes a collection of numbers, converts each to a double,
and sums them up:
public static double sum(Collection<? extends Number> nums) {
double s = 0.0;
for (Number num : nums) s += num.doubleValue();
return s;
}
Well, your second example would allow you to write:
Shape shape = getShapeFromSomewhere();
shapes.add(shape);
whereas you couldn't do that with the first form. It's not useful as often as covariance, I'll grant you.
One area where it can be useful is in terms of comparisons. For example, consider:
class AreaComparer implements Comparator<Shape>
...
You can use that to compare any two shapes... so it would be nice if we could also use it to sort a List<Circle> for example. Fortunately, we can do that with contravariance, which is why there's an overload for Collections.sort of:
public static <T> void sort(List<T> list, Comparator<? super T> c)
For example, when implementing the Collections.addAll() method, you need a collection that can contain some type T or a supertype of T. The method then looks like:
public static <T> void addAll(Collection<? super T> collection, T... objects) {
// Do something
}