Re: implicit <? super T> when an array is a parameter in a generic method

From: Chris Smith (cdsmith_at_twu.net)
Date: 12/13/04


Date: Mon, 13 Dec 2004 15:29:30 -0700

Murat Tasan <mxt6@NOSPAM.NOSPAM.cwru.edu> wrote:
> i guess the true root of the question is, which of the parameters (and
> indeed there may be many) will be going through the inferring process?

The inferral you saw mention of is about the identity of the mystery
type, T. The types of the formal and actual parameters are used as
clues to deduce the value of T. See below.

The type inferrence from generics doesn't apply only to arrays.
However, there is an age-old property of arrays that makes a difference
in your example.

When you call a generic method, the compiler is tasked with discovering
the exact value of the type parameter. It does this by examining each
formal parameter and the corresponding type of its actual parameter. In
your first case, there was no such type parameter which will cause the
arguments to work, so an error message results. Specifically, the
signature and call are:

    public <T> void testMethod(Collection<T> c1, Collection<T> c2)

    testMethod(new HashSet<Integer>(), new HashSet<Number>());

Now, if T were Integer (or anything more specific), then the second
parameter wouldn't work. If T were Number (or anything more general)
then the first parameter wouldn't work. So you get an error message.

However, in your second example, there is a way out. You have:

    public <T> void testMethod(T[] a, Collection<T> c)

    testMethod(new Integer[100], new HashSet<Number>());

Here, if T = Number, everything work fine. The resulting method
signature is:

    public void testMethod(Number[] a, Collection<Number> c)

This may look inappropriate to you, but arrays follow the rather suspect
rule of parallel inheritance; so if Integer extends Number, that implies
that Integer[] extends Number[]. Hence, your method call, which passes
Integer[] for a formal parameter of type Number[], is no more impossible
than passing String to a method that expects Object.

(Note that T must be Number here; anything more specific, and both
parameters fail type checks, but anything more general causes at least
the second parameter to fail type checks.)

It is perfectly appropriate. You may disagree with this rule about
arrays and inheritance. In fact, if you do, join the club. I'm sure
most everyone at Sun is regretting the day they devised such a thing.
However, it's still there and enshrined in the JLS, and has been since
Java first existed. On the other hand, generic collections don't obey
any such rule.

> so when this "inferring" occurs, is there basically a re-writing going
> on the background that equates to changing the function to:
> public <T> void testMethod(T[] a, Collection<? super T> c){...}
>
> ?

No, that's not what's happening. Hopefully, what I've written above is
clear enough to explain the phenomenon.

-- 
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation


Relevant Pages

  • Re: Performance tuning
    ... might want to try using unsafe code, as you can do direct memory management ... also try and turn off bounds checking for arrays in unsafe code if you are ... That is: unless the generics actually ... implemented heuristics on algorithms to speed things up; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Performance tuning
    ... might want to try using unsafe code, as you can do direct memory management ... also try and turn off bounds checking for arrays in unsafe code if you are ... About generics / inheritance. ... implemented heuristics on algorithms to speed things up; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Creating arrays using GENERICS
    ... According to the book I read by Schildt: "Arrays of specific generic ... using generics and just defining it like this: ... Generics are a compile time feature, and not a run time feature as I ...
    (comp.lang.java.programmer)
  • Re: Performance tuning
    ... About generics / inheritance. ... implemented heuristics on algorithms to speed things up; ... on arrays - like sorting, but also like filtering, array ... then performance tuning for the sake of performance tuning ...
    (microsoft.public.dotnet.languages.csharp)