RFR: JDK-8242943 Fix all remaining unchecked warnings in jdk.hotspot.agent

Joe Darcy joe.darcy at oracle.com
Mon Apr 20 19:19:12 UTC 2020


Hello,

On 4/16/2020 5:47 AM, Magnus Ihse Bursie wrote:
[snip]
> The tricky one here is the helper TableModelComparator. This one took 
> me a while to wrap my head around. It implements Comparator, but the 
> compare() method takes "rows" from the model, which are just expressed 
> as Objects, and left to subclasses to define differently. For one of 
> the subclasses it uses the type T that the TableModel is created 
> around, but in other it uses an independent domain model. :-/ Anyway. 
> The compare() method then extracts data for the individual columns of 
> each row using the method getValueForColumn(), and compare them 
> pairwise. This data from the rows are supposed to implement Comparable.
>
> In the end, I think I got it pretty OK, but I'm still an apprentice 
> when it comes to generics black magic. The subclasses of 
> TableModelComparator want to return different objects from 
> getValueForColumn() for different columns in the row, like Long or 
> String. They are all Comparable, but String is Comparable<String> and 
> Long is Comparable<Long>. So I needed to specify the abstract method 
> as returning Comparable<?>, since Comparable<String> is not 
> Comparable<Object>.
>
> But then, for reasons that I do not fully fathom, I could not specify
>
> Comparable<?> o1 = getValueForColumn(row1, columns[i]);
> Comparable<?> o2 = getValueForColumn(row2, columns[i]);
> int result = o1.compareTo(o2);
>
> because the compiler did not accept the call to compareTo().
>
> I did try to sacrifice a black rooster at midnight and walking 
> backwards in a circle three time, to no avail. Maybe the problem was 
> that it was not full moon or that I have no cat. In the end, I casted 
> o1 and o2 to Comparable<Object> and suppressed the warning for that cast.
>
> If anyone knows what rituals I need to perform to make this work, or 
> -- even better -- how to fix the code properly, please let me know!

A brief discussion of wildcards, ?. The meaning of a wildcard is some 
particular unknown type, meeting the various  constraints from "? 
extends" or "? super".  If there is no explicit constraint listed, it is 
equivalent to "? extends Object".

So the meaning of the code above is something

Comparable<S> o1 = getValueForColumn(row1, columns[i]);
Comparable<T> o2 = getValueForColumn(row2, columns[i]);

where S and T are two fresh, unrelated type variables. Concretely, this 
means S and T could be, say, String and Integer so that is why a call to 
o1.compareTo(o2) would not be accepted by the compiler since Strings and 
Integer aren't comparable to each other.

While two instances of "Comparable<?>" are syntactically the same, they 
don't represent the same type inside the compiler.

In some cases, you can get around this issue by using a separate method 
to capture the type variable and then use it more than once. A technique 
we've used in the JDK is to have a pubic method with a wildcards calling 
a private method using a type variable. I've looked around for a few 
minutes and didn't find a concrete example in the JDK, but they're in there.

I haven't looked over the specific code here in much detail; the type 
Comparable<Object> might to be the best you can do, but it isn't very 
expressive since Object's aren't necessarily comparable.

HTH,

-Joe




More information about the build-dev mailing list