4

The following code:

import java.util.*;

public final class JavaTest {
    public static <T extends Comparable<? super T>> int max(List<? extends T> list, int begin, int end) {
        return 5;
    }

    public static void main(String[] args) {
        List<scruby<Integer>> List = new ArrayList<>();
        JavaTest.<scruby>max(List, 0, 0); //how does this compile?, scruby doesn't meet
        //T extends Comparable<? super T>
    }
}

class scruby<T> implements Comparable<String>{
    public int compareTo(String o) {
        return 0;
    }
}

How does the statement JavaTest.max(List, 0, 0) compile? How does scruby meet the

T extends Comparable <? super T>

It implements Comparable<String> which isn't a super type of scruby? If you change it to scruby<Integer> it won't compile and give the error. So why does it compile now? Why does the raw type compile?

nhooyr
  • 1,104
  • 1
  • 13
  • 31
  • Can't see the point of someone downvoting this? At least for me it seems like legit question. – Roope Hakulinen Dec 22 '14 at 19:55
  • 2
    No it does not extend `String` it extends `Integer` because of `List> List = new ArrayList<>();` and then it is not using your `implements Comparable` method it is using the [compareTo](http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#compareTo(java.lang.Integer)) method inherited from `Integer` – chancea Dec 22 '14 at 19:56
  • Sorry I meant it implements Comparable and string isn't a super of scruby. How does it inherit anything from Integer? – nhooyr Dec 22 '14 at 20:34

1 Answers1

3
JavaTest.<scruby>max(List, 0, 0);

scruby is a raw type. This suppresses some of the type checks.

You should add all required type parameters:

JavaTest.<scruby<Integer>>max(List, 0, 0);

Or just let Java infer them:

JavaTest.max(List, 0, 0);
Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
  • Oh, so because it is a raw type, it just doesn't check? O.O Interesting, thanks for your help! – nhooyr Dec 22 '14 at 20:42
  • 1
    Yes. Basically, as soon as you introduce a raw type, all generic type checks that relate to it are suppressed, except for warnings, and checking is relegated to runtime, as it was in the days before generics. Remember that Java expects use of raw types to be limited to old, legacy code. – RealSkeptic Dec 22 '14 at 20:51