generics question.

Discussion in 'Java' started by Amarnath B S, Nov 28, 2005.

  1. Amarnath B S

    Amarnath B S Guest

    Could anyone help me by explaining the behaviour below?

    ----------code snippet start-----------

    static <T> void some( T a[], Collection<T> c){
    //nothing
    }
    .....
    some(new Number[100], new ArrayList<Float>()); //compile time error
    some(new Float[100], new ArrayList<Number>());//allowed
    -----------code snippet end-------------

    Why is the first method invocation not allowed? How does the compiler
    compare the type dependencies?

    thanks in advance,
    Amarnath
     
    Amarnath B S, Nov 28, 2005
    #1
    1. Advertising

  2. Amarnath B S wrote (in a different order):
    >
    > static <T> void some( T a[], Collection<T> c){
    > //nothing
    > }
    >
    > Why is the first method invocation not allowed? How does the compiler
    > compare the type dependencies?


    > some(new Number[100], new ArrayList<Float>()); //compile time error


    The second argument implies that T is Float. Number[] is not assignable
    to Float[].

    > some(new Float[100], new ArrayList<Number>());//allowed


    The second argument implies that T is Number. Float[] is assignable to
    Number[].

    Array types are quite eccentric. Best off sticking to collections.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
     
    Thomas Hawtin, Nov 28, 2005
    #2
    1. Advertising

  3. Amarnath B S

    Roedy Green Guest

    On Mon, 28 Nov 2005 18:46:54 +0530, "Amarnath B S" <>
    wrote, quoted or indirectly quoted someone who said :

    >static <T> void some( T a[], Collection<T> c){
    > //nothing
    > }
    >....
    >some(new Number[100], new ArrayList<Float>()); //compile time error
    >some(new Float[100], new ArrayList<Number>());//allowed


    If machines were sentient, I think this get you a jail term for
    compiler abuse.

    I think the answer may become clear if in your call instead of relying
    on type inference you used an explicit type in the invocation.

    Another hint. Try reversing the order of the parms to some.


    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Nov 28, 2005
    #3
  4. Amarnath B S

    Amarnath Guest

    "Roedy Green" <> wrote in
    message news:...
    > On Mon, 28 Nov 2005 18:46:54 +0530, "Amarnath B S" <>
    > wrote, quoted or indirectly quoted someone who said :
    >
    > >static <T> void some( T a[], Collection<T> c){
    > > //nothing
    > > }
    > >....
    > >some(new Number[100], new ArrayList<Float>()); //compile time error
    > >some(new Float[100], new ArrayList<Number>());//allowed

    >
    > If machines were sentient, I think this get you a jail term for
    > compiler abuse.
    >
    > I think the answer may become clear if in your call instead of relying
    > on type inference you used an explicit type in the invocation.
    >
    > Another hint. Try reversing the order of the parms to some.
    >
    >
    > --
    > Canadian Mind Products, Roedy Green.
    > http://mindprod.com Java custom programming, consulting and coaching.


    Compiler abuse!! I was just trying to understand it!! Anyway..,
    Yes, I could have used explicit types, but I would like to understand the
    compiler's behaviour here.

    static <T> void some(Collection<T> c, T a[]){
    }
    .........
    some(new ArrayList<Float>(), new Number[100]);

    The above does not compile either.

    -Amarnath
     
    Amarnath, Nov 29, 2005
    #4
  5. Amarnath B S

    Amarnath Guest

    "Thomas Hawtin" <> wrote in message
    news:438b0faa$0$1455$...
    > Amarnath B S wrote (in a different order):
    > >
    > > static <T> void some( T a[], Collection<T> c){
    > > //nothing
    > > }
    > >
    > > Why is the first method invocation not allowed? How does the compiler
    > > compare the type dependencies?

    >
    > > some(new Number[100], new ArrayList<Float>()); //compile time error

    >
    > The second argument implies that T is Float. Number[] is not assignable
    > to Float[].
    >
    > > some(new Float[100], new ArrayList<Number>());//allowed

    >
    > The second argument implies that T is Number. Float[] is assignable to
    > Number[].
    >
    > Array types are quite eccentric. Best off sticking to collections.
    >
    > Tom Hawtin
    > --
    > Unemployed English Java programmer
    > http://jroller.com/page/tackline/



    If that is the case, then
    static <T> void some(Collection<T> c, T a[]){
    }
    .........
    some(new ArrayList<Float>(), new Number[100]);

    should compile well. But it doesn't !!

    -Amarnath
     
    Amarnath, Nov 29, 2005
    #5
  6. Amarnath schreef:
    > "Thomas Hawtin" <> wrote in message
    > news:438b0faa$0$1455$...
    >
    >>Amarnath B S wrote (in a different order):
    >>
    >>>static <T> void some( T a[], Collection<T> c){
    >>> //nothing
    >>> }
    >>>
    >>>Why is the first method invocation not allowed? How does the compiler
    >>>compare the type dependencies?

    >>
    >> > some(new Number[100], new ArrayList<Float>()); //compile time error

    >>
    >>The second argument implies that T is Float. Number[] is not assignable
    >>to Float[].
    >>
    >> > some(new Float[100], new ArrayList<Number>());//allowed

    >>
    >>The second argument implies that T is Number. Float[] is assignable to
    >>Number[].
    >>
    >>Array types are quite eccentric. Best off sticking to collections.
    >>
    >>Tom Hawtin
    >>--
    >>Unemployed English Java programmer
    >>http://jroller.com/page/tackline/

    >
    >
    >
    > If that is the case, then
    > static <T> void some(Collection<T> c, T a[]){
    > }
    > ........
    > some(new ArrayList<Float>(), new Number[100]);
    >
    > should compile well. But it doesn't !!


    Read about arrays in the essay on generics. It is quite complex, and
    quite a nuisance, for instance, you cannot do something like

    List<State>[] stateList = new List<State>[15];

    Only

    List<?>[] stateList = new List<?>[15];

    or

    List<State>[] stateList = new List[15]; (*)

    are allowed, the first making it impossible to add anything to the lists
    and needing explicit casts when asking for one of the elements of the
    list, the second generating an "unchecked" warning. The reason is that
    generics are only in the compiler, and as arrays are also objects, they
    can be assigned to Object variables, which leads to all kinds of problems.

    See http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf, section 7.3,
    but note that there is an error in there, specifically about the line (*).
    Also read the section about fun with wildcards, which will probably
    solve your problem above: you can write

    static <T> void some(Collection<T> c, <? super T> a[]){
    }
    .........
    some(new ArrayList<Float>(), new Number[100]);

    H.

    --
    Hendrik Maryns

    ==================
    www.lieverleven.be
    http://aouw.org
     
    Hendrik Maryns, Nov 29, 2005
    #6
  7. Amarnath wrote in news:1133255627.68550@sj-nntpcache-5:
    > static <T> void some(Collection<T> c, T a[]){
    > }
    > ........
    > some(new ArrayList<Float>(), new Number[100]);
    >
    > The above does not compile either.


    Would you want it to compile? If I was writing a function some
    (Collection<T> c, T a[]), I would sure want to be able to put the
    elements of 'a' into 'c'. But how can I do that if 'a' is an array of
    all kinds of Numbers and 'c' can only hold Floats?

    If you make it explicit that 'c' and 'a' hold the same kind of things,
    then why would you want to start putting something else in there?

    Of course, arrays are a different thing than collections; arrays are
    more powerful and even a little dangerous. Float[] is a subtype of
    Number[], so you can pass in a Float[] where a Number[] is expected
    without complaint and everything works just right. That's why some(new
    ArrayList<Number>(), new Float[100]) would work, because it is expecting
    a Number[] but accepts a Float[]. If you try to put something from 'c'
    into 'a' that isn't actually a Float, you'll get a runtime exception.

    Some people seem to think that arrays are worse than collections because
    of this, if I understand their posts correctly, but I probably don't
    because I don't see a problem with it. I wish collections could be as
    powerful as arrays! Then I could do away with using real arrays all
    together.
     
    Brendan Guild, Nov 29, 2005
    #7
  8. Amarnath wrote:
    > "Thomas Hawtin" <> wrote in message
    > news:438b0faa$0$1455$...
    >
    >>Amarnath B S wrote (in a different order):
    >>
    >>>static <T> void some( T a[], Collection<T> c){
    >>> //nothing
    >>> }
    >>>
    >>>Why is the first method invocation not allowed? How does the compiler
    >>>compare the type dependencies?

    >>
    >> > some(new Number[100], new ArrayList<Float>()); //compile time error

    >>
    >>The second argument implies that T is Float. Number[] is not assignable
    >>to Float[].
    >>
    >> > some(new Float[100], new ArrayList<Number>());//allowed

    >>
    >>The second argument implies that T is Number. Float[] is assignable to
    >>Number[].


    > If that is the case, then
    > static <T> void some(Collection<T> c, T a[]){
    > }
    > ........
    > some(new ArrayList<Float>(), new Number[100]);
    >
    > should compile well. But it doesn't !!


    I really don't follow your logic there at all. Applying my argument as
    above to this example:

    The argument "new ArrayList<Float>()", of type ArrayList<Float>, implies
    that T is Float. The argument "new Number[100]", of type Number[], is
    not assignable to Float[].

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
     
    Thomas Hawtin, Nov 29, 2005
    #8
  9. Amarnath B S

    Oliver Wong Guest

    "Brendan Guild" <> wrote in message
    news:Xns971D3BACEE9D2bguild31425@64.59.144.76...
    >
    > Of course, arrays are a different thing than collections; arrays are
    > more powerful and even a little dangerous. Float[] is a subtype of
    > Number[], so you can pass in a Float[] where a Number[] is expected
    > without complaint and everything works just right. That's why some(new
    > ArrayList<Number>(), new Float[100]) would work, because it is expecting
    > a Number[] but accepts a Float[]. If you try to put something from 'c'
    > into 'a' that isn't actually a Float, you'll get a runtime exception.
    >
    > Some people seem to think that arrays are worse than collections because
    > of this, if I understand their posts correctly, but I probably don't
    > because I don't see a problem with it. I wish collections could be as
    > powerful as arrays! Then I could do away with using real arrays all
    > together.


    Under your definition of "more powerful", I think Collections are
    actually more powerful than arrays. If you want to say "I want a collection
    of Numbers, but I'm willing to take a collection of Floats, 'cause Floats
    are Numbers, and I'm just planning on pulling stuff out of the collection."
    then you would write, for example "ArrayList<? extends Number>". So with
    this syntax alone, Collections are of the same power as arrays. But you have
    more control over Collections.

    You can also say "I want a collection. I don't care what kind of
    collection it is, but I wanna be able to put Numbers in it, so if you give
    me a collection of Objects, that's okay too." The syntax is "ArrayList<?
    super Number>".

    Finally you can say "I want a collection of Numbers and nothing but
    numbers. Collection of Floats is no good, because I may want to insert
    Numbers, and collection of Objects is no good, because I want to be sure
    that when I take an element out, it's a Number". The syntax for that is
    "ArrayList<Number>".

    - Oliver
     
    Oliver Wong, Nov 29, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. geoffrey wall

    question on generics, constants in vhdl

    geoffrey wall, Oct 1, 2005, in forum: VHDL
    Replies:
    1
    Views:
    652
    Mike Treseler
    Oct 1, 2005
  2. Roger Levy
    Replies:
    20
    Views:
    912
    Neal Gafter
    Jan 5, 2005
  3. Joona I Palaste

    Generics question

    Joona I Palaste, Oct 14, 2004, in forum: Java
    Replies:
    6
    Views:
    484
    Vincent Cantin
    Oct 15, 2004
  4. Juergen Berchtel
    Replies:
    1
    Views:
    6,028
    John C. Bollinger
    May 20, 2005
  5. Soul
    Replies:
    0
    Views:
    532
Loading...

Share This Page