Problem with generic

B

Benjamin Lerman

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.
 
O

Oliver Wong

Benjamin Lerman said:
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
 
B

Benjamin Lerman

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
 
O

Oliver Wong

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


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
 
T

Thomas Hawtin

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top