shampouya
asked on
Why is this type bound incorrect?
My textbook says the type bound inside the angled brackets of the code below is incorrect. Then it said adding "extends Comparable" inside the angle brackets is naive. I typed out the paragraph from the textbook. Why does it say this solution is naive?
"Suppose we want to write a findMax routine. Consider the code below. This code cannot work because the compiler cannot prove that the call to compareTo at line 6 is valid; compareTo is guaranteed to exist only if AnyType is Comparable. We can solve this problem by using a type bound. The type bound is specified inside the angle brackets <>, and it specifies properties that the parameter types must have. A naive attempt is to rewrite the signature as:
public static <AnyType extends Comparable>...
This is naive because, as we know, the Comparable interface is now generic."
"Suppose we want to write a findMax routine. Consider the code below. This code cannot work because the compiler cannot prove that the call to compareTo at line 6 is valid; compareTo is guaranteed to exist only if AnyType is Comparable. We can solve this problem by using a type bound. The type bound is specified inside the angle brackets <>, and it specifies properties that the parameter types must have. A naive attempt is to rewrite the signature as:
public static <AnyType extends Comparable>...
This is naive because, as we know, the Comparable interface is now generic."
public static <AnyType> AnyType findMax( AnyType[] arr)
{
int maxIndex = 0;
for(int i=1; i<arr.length; i++)
if(arr[i].compareTo(arr[maxIndex]) > 0)
maxIndex = i;
return arr[maxIndex];
}
ASKER
That's a little too complicated for me. I just started working with generic types and I don't know much about compareTo.
This code compiles without warning because
compilr know that type T implement generic comarable<T> interfcae
so it can use compareTo method insde the method findMax
compilr know that type T implement generic comarable<T> interfcae
so it can use compareTo method insde the method findMax
public static <T extends Comparable<T>> T findMax( T[] arr)
{
int maxIndex = 0;
for(int i=1; i<arr.length; i++)
if(arr[i].compareTo(arr[maxIndex]) > 0)
maxIndex = i;
return arr[maxIndex];
}
I may be on the wrong track but you might want to read
http://en.wikipedia.org/wiki/Generics_in_Java#Wildcards
and
http://en.wikipedia.org/wiki/Wildcard_%28Java%29
http://en.wikipedia.org/wiki/Generics_in_Java#Wildcards
and
http://en.wikipedia.org/wiki/Wildcard_%28Java%29
Of course "T" can be everywhere re[laced by "AnyType" as you hasd it before
public static <AnyType extends Comparable<AnyType>> AnyType findMax( AnyType[] arr)
{
int maxIndex = 0;
for(int i=1; i<arr.length; i++)
if(arr[i].compareTo(arr[maxIndex]) > 0)
maxIndex = i;
return arr[maxIndex];
}
If you make it like that (see below; Comparable without <AnyType> as you suiggested in the beginning)
then it will still compile but will give unchecked warning
because compiler will not know that your type AnyType implements Comparable interface
which has method comparing values specifically of AnyType type
then it will still compile but will give unchecked warning
because compiler will not know that your type AnyType implements Comparable interface
which has method comparing values specifically of AnyType type
public static <AnyType extends Comparable> AnyType findMax( AnyType[] arr)
{
int maxIndex = 0;
for(int i=1; i<arr.length; i++)
if(arr[i].compareTo(arr[maxIndex]) > 0)
maxIndex = i;
return arr[maxIndex];
}
> naive attempt is to rewrite the signature as
>This is naive because, as we know, the Comparable interface is now generic
"naive" is a nice way of saying "not very informed", "not very smart"
because Comarable should be used in its generic form applied to the same generic type which is mentioned in the declaration,
so they basically meant the same thing, that one should use
public static <AnyType extends Comparable<AnyType>> AnyType findMax( AnyType[] arr)
instaed of this:
public static <AnyType extends Comparable> AnyType findMax( AnyType[] arr)
(see my posts above)
ASKER
Your posts are helpful, but in my mind I don't see the connection between these two things:
1. <AnyType extends Comparable<AnyType>>
2. the AnyType class implements Comparable interface
That's confusing because (1.) uses the word "extends" and (2.) uses the word "implements", why is that? I didn't realize that you could extend an interface. I thought you could only implement.
Also confusing, why is an interface like Comparable given angled brackets and treated like a generic collection? I thought Comparable was just a simple interface, and I didn't think it could be treated like a generic collection.
1. <AnyType extends Comparable<AnyType>>
2. the AnyType class implements Comparable interface
That's confusing because (1.) uses the word "extends" and (2.) uses the word "implements", why is that? I didn't realize that you could extend an interface. I thought you could only implement.
Also confusing, why is an interface like Comparable given angled brackets and treated like a generic collection? I thought Comparable was just a simple interface, and I didn't think it could be treated like a generic collection.
Comparable<AnyType> is designation of the type ; so AnyType should be the type which extends the type which implements Comparable with respect to AnyType
So it does not extend interface - it extends the type(class) inmplementing interface. in general "T" in generic is substitute for Type
(Type is broader than class - Type may be either instance of class or instance of class implementing Interface).
So there is no class Comparable but there is type Comaparable
generic is by no means necessarrily Collection; generic can be also method and as method can be generic, so interface can be generic
and even class can be generic, see here for example:
http://download.oracle.com/javase/tutorial/java/generics/gentypes.html
Certainly generic is much more general than generic collections, as you see
so in this case AnyType should extend the type which implements generic interface Comparable<AnyType>
So it does not extend interface - it extends the type(class) inmplementing interface. in general "T" in generic is substitute for Type
(Type is broader than class - Type may be either instance of class or instance of class implementing Interface).
So there is no class Comparable but there is type Comaparable
generic is by no means necessarrily Collection; generic can be also method and as method can be generic, so interface can be generic
and even class can be generic, see here for example:
http://download.oracle.com/javase/tutorial/java/generics/gentypes.html
Certainly generic is much more general than generic collections, as you see
so in this case AnyType should extend the type which implements generic interface Comparable<AnyType>
We should not think about generics only in connection with Collections
Collections are just the most famous case
In general any class can be generic if some field in the class has parametrized type,.
This class is the wrapper arround the instance of any type:
Once the class can be generic, so the method can be generic
and interface can be generic
And collections with parametrized type of their elements are just very important and natural cases of generics
Collections are just the most famous case
In general any class can be generic if some field in the class has parametrized type,.
This class is the wrapper arround the instance of any type:
public class Box<T> {
private T t; // T stands for "Type"
public void setEntity(T t) {
this.t = t;
}
public T getEntity() {
return t;
}
}
Once the class can be generic, so the method can be generic
and interface can be generic
And collections with parametrized type of their elements are just very important and natural cases of generics
ASKER
Ok that makes sense. The only thing I don't understand now is why Comparable<AnyType> is considered a type and not an interface. Does adding the <AnyType> next to the Comparable interface turn it into a type?
No , any interface corresponds to type.
Type is a broader idea than the class.
Type is anything you can use in the declaration of variable.
You can declare variable in the code, e.g.
Comparable c = new String("abc");
Anything you can use in the declaration of varaible is a Type.
So Type can be either class or interface, because interface may be used in order to declare the type of the variable along with the class.
Therefore Comparable is a Type
and
Comparable<AnyType> is also a Type , just generic type with parameter AnyType
Type is a broader idea than the class.
Type is anything you can use in the declaration of variable.
You can declare variable in the code, e.g.
Comparable c = new String("abc");
Anything you can use in the declaration of varaible is a Type.
So Type can be either class or interface, because interface may be used in order to declare the type of the variable along with the class.
Therefore Comparable is a Type
and
Comparable<AnyType> is also a Type , just generic type with parameter AnyType
any Comparable represents a Type
Comparable<AnyType> just emphasizes that this is the type for which
the method compareTo(AnyType o) is defined, where AnyType is the same Type which
is used in the geteneric method AnyType findMax( AnyType[] arr)
That's why it is important to write
T extends Comparable<T> (I'm writing T as it is shourter than AnyType and there is obviously no difference)
in declaration:
public static <T extends Comparable<T>> T findMax( T[] arr)
It means that we need type which extends some other type which implements method compareTo(T o)
where T is the same type which is returned by this method and the same type which array is ion the argument
and the same type which is mentioned in the body of the method
If you don't write this way <T extends Comparable<T>> and just write <T extends Comparable> then compiler cannot be sure
that method
arr[i].compareTo(arr[maxIndex])
is defined because element of array arr is isntance of T, therefore compiler needs just this way <T extends Comparable<T>> and this<T extends Comparable> is not sufficient for compiler to be sure that this method is defined
ASKER
Ok so allow me explain <T extends Comparable<T>> crudely and tell me if I'm basically correct:
"The first T inside the angled brackets allows my method to make use of this generic type T. Then, the Comparable<T> part that we extend, that means that our generic type T inherits the abilities of a type Comparable<T>, which implements the compareTo method specifically using the generic type T. And since we extend that type, we can now use the compareTo method in our findMax method for any type of argument passed into the findMax method."
"The first T inside the angled brackets allows my method to make use of this generic type T. Then, the Comparable<T> part that we extend, that means that our generic type T inherits the abilities of a type Comparable<T>, which implements the compareTo method specifically using the generic type T. And since we extend that type, we can now use the compareTo method in our findMax method for any type of argument passed into the findMax method."
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks mate
perhaps this exaplanation will help:
http://stackoverflow.com/questions/2231804/java-interface-extends-comparable