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 build-dev mailing list