Problem with generic

Discussion in 'Java' started by Benjamin Lerman, Jul 10, 2006.

  1. Hi all,

    Let's assume I have something that looks like the following:

    import java.io.Serializable;

    class A {

    public static <K extends Serializable> K getFoo(Class<K> c) {
    return c.newInstance();
    }

    public static <K extends Serializable> K getBar(K d) {
    return getFoo(d.getClass());
    }
    }

    When I try to compile that, I found:

    dara /tmp $ javac A.java
    A.java:10: incompatible types
    found : java.io.Serializable
    required: K
    return getFoo(c.getClass());
    ^
    1 error

    Is there a reason for the compiler to refuse such a method ?

    Thanks.

    --
    Benjamin Lerman
     
    Benjamin Lerman, Jul 10, 2006
    #1
    1. Advertising

  2. Benjamin Lerman

    Oliver Wong Guest

    "Benjamin Lerman" <> wrote in message
    news:...
    > Hi all,
    >
    > Let's assume I have something that looks like the following:
    >
    > import java.io.Serializable;
    >
    > class A {
    >
    > public static <K extends Serializable> K getFoo(Class<K> c) {
    > return c.newInstance();
    > }
    >
    > public static <K extends Serializable> K getBar(K d) {
    > return getFoo(d.getClass());
    > }
    > }
    >
    > When I try to compile that, I found:
    >
    > dara /tmp $ javac A.java
    > A.java:10: incompatible types
    > found : java.io.Serializable
    > required: K
    > return getFoo(c.getClass());
    > ^
    > 1 error
    >
    > Is there a reason for the compiler to refuse such a method ?


    Your source code says d.getClass() but your error says c.getClass().
    Maybe you didn't compile the correct source code?

    If you add the exception handling code (it might throw
    InstantiationException and IllegalAccessException) it compiles fine on my
    side.

    - Oliver
     
    Oliver Wong, Jul 10, 2006
    #2
    1. Advertising

  3. > Your source code says d.getClass() but your error says c.getClass().
    > Maybe you didn't compile the correct source code?


    I did. But I changed the code I wrote because I did not want to have
    the 2 variables having the same name.

    > If you add the exception handling code (it might throw
    > InstantiationException and IllegalAccessException) it compiles fine on my
    > side.


    What compiler are you using? Because I can compile that code inside
    eclipse, but I cannot with javac. To take care of the Exception, this
    code does not compile on my side:

    dara /tmp $ cat A.java; javac A.java
    import java.io.Serializable;

    abstract class A {

    public abstract <K extends Serializable> K getFoo(Class<K> c);

    public <K extends Serializable> K getBar(K d) {
    return getFoo(d.getClass());
    }
    }
    A.java:8: incompatible types
    found : java.io.Serializable
    required: K
    return getFoo(d.getClass());
    ^
    1 error
    zsh: exit 1 javac A.java
     
    Benjamin Lerman, Jul 10, 2006
    #3
  4. Benjamin Lerman

    Oliver Wong Guest

    "Benjamin Lerman" <> wrote in message
    news:...
    >> Your source code says d.getClass() but your error says c.getClass().
    >> Maybe you didn't compile the correct source code?

    >
    > I did. But I changed the code I wrote because I did not want to have
    > the 2 variables having the same name.
    >
    >> If you add the exception handling code (it might throw
    >> InstantiationException and IllegalAccessException) it compiles fine on my
    >> side.

    >
    > What compiler are you using? Because I can compile that code inside
    > eclipse, but I cannot with javac. To take care of the Exception, this
    > code does not compile on my side:
    >
    > dara /tmp $ cat A.java; javac A.java
    > import java.io.Serializable;
    >
    > abstract class A {
    >
    > public abstract <K extends Serializable> K getFoo(Class<K> c);
    >
    > public <K extends Serializable> K getBar(K d) {
    > return getFoo(d.getClass());
    > }
    > }
    > A.java:8: incompatible types
    > found : java.io.Serializable
    > required: K
    > return getFoo(d.getClass());
    > ^
    > 1 error
    > zsh: exit 1 javac A.java


    I used Eclipse. Its compiler is a little bit smarter about inferring
    generic types based on return values.

    - Oliver
     
    Oliver Wong, Jul 10, 2006
    #4
  5. Oliver Wong wrote:
    >
    > "Benjamin Lerman" <> wrote in message
    > news:...
    >>
    >> What compiler are you using? Because I can compile that code inside
    >> eclipse, but I cannot with javac. To take care of the Exception, this
    >> code does not compile on my side:
    >>
    >> dara /tmp $ cat A.java; javac A.java
    >> import java.io.Serializable;
    >>
    >> abstract class A {
    >>
    >> public abstract <K extends Serializable> K getFoo(Class<K> c);

    public abstract <J extends Serializable> J getFoo(Class<J> c);
    >>
    >> public <K extends Serializable> K getBar(K d) {
    >> return getFoo(d.getClass());
    >> }
    >> }
    >> A.java:8: incompatible types
    >> found : java.io.Serializable
    >> required: K
    >> return getFoo(d.getClass());
    >> ^
    >> 1 error
    >> zsh: exit 1 javac A.java


    1.6 comes back with a more accurate message:

    [tackline@new scratch]$ javac A.java
    A.java:8: incompatible types
    found : capture#768 of ? extends java.io.Serializable
    required: K
    return getFoo(d.getClass());
    ^
    1 error

    > I used Eclipse. Its compiler is a little bit smarter about inferring
    > generic types based on return values.


    Smart, but wrong.

    It's a bit difficult to follow because K has been used for two different
    parameters. To make it clearer assume K has been replaced by J in the
    first instance, as above.

    The type of d.getClass() is not Class<? extends K>, but Class<? extends
    |K|> where |K| is the erasure of K. So in this instance J is "capture of
    ? extends |K|" and getFoo returns that type.

    To be more concrete, consider List<String> list; ... getBar(list).
    d.getClass() will be List, not List<String>. getFoo will returns List,
    without a generic type argument. That is incompatible with List<String>
    (normaly you would just get a warning, but as you are really using
    generics you get an error).

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
     
    Thomas Hawtin, Jul 10, 2006
    #5
    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. Murat Tasan
    Replies:
    1
    Views:
    8,052
    Chaitanya
    Feb 3, 2009
  2. Replies:
    2
    Views:
    437
  3. =?ISO-8859-1?Q?paul_k=F6lle?=

    hmm, lets call it: generic __init__ problem

    =?ISO-8859-1?Q?paul_k=F6lle?=, Feb 17, 2004, in forum: Python
    Replies:
    7
    Views:
    338
    Michele Simionato
    Feb 21, 2004
  4. Showjumper

    Problem: getting generic error in gdi+

    Showjumper, Sep 25, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    365
  5. minlearn
    Replies:
    2
    Views:
    457
    red floyd
    Mar 13, 2009
Loading...

Share This Page