10
public class Main {

    public static <T> void foo(T[] bar) {
        double d = (double) bar[0]; // Error : incompatible types
    }

    public static void main(String[] args) {
        int[] int_buf = new int[8];
        foo(int_buf);
    }
}

The issue is indicated in the code.

Why does Java generics not allow type conversion on generic types?

xmllmx
  • 39,765
  • 26
  • 162
  • 323

3 Answers3

15

The problem is deeper than this. Even without the line you highlighted, this program is broken:

public class Main {
    public static <T> void foo(T[] bar) {
        // do nothing
    }

    public static void main(String[] args) {
        int[] int_buf = new int[8];
        foo(int_buf);   <-- problem is here
   }
}

Java generics only support reference types as type parameters; the generic method foo() could be rewritten as follows:

<T extends Object> void foo(T[] bar) { ... }

And here's your problem: there's no T that extends Object such that an int[] is a T[].

Secondarily, the reason the conversion also fails is that we know nothing about T, so we don't know that there exists a conversion from T to double.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
13

This is because you are not specifiying what the generic type T is. So by default it will think T is an object type, not a number. It's not possible to cast an object to a double, this makes no sense.

If you change to <T extends Number> this should work just fine. Although, you might need to have an Integer array rather than a int array

Gaktan
  • 458
  • 3
  • 9
  • If the given array is already int[] rather than Integer[], is there any way to make it work? – xmllmx Mar 25 '16 at 04:03
  • Great mention that `` will work; +1 from me – Debosmit Ray Mar 25 '16 at 04:03
  • 8
    @xmllmx It will not work since `int` is an primitive type not an object type. – SatyaTNV Mar 25 '16 at 04:06
  • 2
    @xmllmx Have a look here on the link bellow. If you are using Java 8, you might be able to do it easily. But I'm pretty sure memory is copied in any case, no way around this. http://stackoverflow.com/questions/880581/how-to-convert-int-to-integer-in-java – Gaktan Mar 25 '16 at 04:14
  • I'm curious about the title of the question and came in, but have no idea what this question and accepted answer are talking about. Correct me if I'm wrong. I think the problem is described by @Satya and it's not about **type conversion on generic types**, I can compile and run it if `int_buf` is an array of `Integer` instead of `int`. And I don't need to use `` at all. – Nier Mar 25 '16 at 04:49
  • @Nier Problem is, if you pass any Object array other than primitive type, the double cast will fail. The generic type here is just to make sure you don't give it just any kind of array – Gaktan Mar 25 '16 at 04:57
  • @Nier I think the question is about why you can't cast a `T` to a `double`. The issue has become clouded because there are 2 lines of the original code that don't compile. I'm not sure what the `` thing is about - that doesn't solve either of the problems. – Paul Boddington Mar 25 '16 at 05:03
  • If you make ``, it's smarter to to `bar[0].doublevalue()` in the method, instead of casting – Ferrybig Mar 25 '16 at 13:28
  • "So by default it will think T is an object type, not a number." It's not "by default". `T` is a reference type, and can only represent a reference type. – newacct Mar 29 '16 at 22:13
-2

The Java compiler erases all type parameters in generic code. A direct consequence of this is that you cannot verify which parameterized type for a generic is currently is use. If you test, instanceof will not work either. Since, runtime does not keep track of a type parameters in java, there is no difference between HashSet<Integer> and HashSet<Double>. You can do a ..instanceof HashSet<?> at the most to check if it is an instance of a HashSet.

If something is not clear in what I have written, please refer to the docs.

Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43