RFR: JDK-8242943 Fix all remaining unchecked warnings in jdk.hotspot.agent
Magnus Ihse Bursie
magnus.ihse.bursie at oracle.com
Tue Apr 21 11:56:25 UTC 2020
On 2020-04-20 21:19, Joe Darcy wrote:
> 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.
Ah, right, and compareTo -- in contrast with equals() -- only compares
to objects of the same type. I think that's part of what confused me here.
>
> 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.
Thank you for taking time to explain this!
/Magnus
>
> HTH,
>
> -Joe
>
More information about the serviceability-dev
mailing list