Kam
Kam

Reputation: 6008

Can I do type inference in Java? Yes I can

I am an experienced C++ developer learning Java abstract concepts.

I was looking if I can do type inference in java and the answer is usually no and that I need to pass the Class type when calling a generic function. like so:

<T> void test(T t, Class<T> clazz);

I though this is redundant and that the compiler should be able to infer the type (C++ does it why can't Java :p) but then when I understood how generics are implemented under the hood I realized that T is essentially Object at runtime.

But then I realized that I can still call Object member functions on an instance of T. So I'm able to do something like this:

<T> void test(T t) {
    if (t.getClass() == Integer.class ) {
        // T is of type Integer.
    }
}

1- Is there an advantage of either techniques over the other (i.e. passing Class<T> over checking Class type using getClass)?

2- Is there anything wrong with the second approach? The reason I am asking is that I have seen people go to the extend of using reflection and some obscure techniques before following what I've written above. Ideas?

Upvotes: 0

Views: 92

Answers (2)

ruakh
ruakh

Reputation: 183456

There are a few issues here:

  • In general, you shouldn't really be inspecting the types of things at runtime. It's not wrong, per se, but if you feel the need to do it, then you're probably taking the wrong approach. For generics, for example, the whole point of a generic method is that it works regardless of the type argument.
    • Unlike C++, Java doesn't have any concept of template specialization; and Java programmers are comfortable with this restriction. Idiomatic Java code does not try to circumvent it.
  • There's no guarantee that t.getClass() is the same as the type T; t could be an instance of a subtype of T, for example. (Whereas a Class<T> is guaranteed to be the type T, unless it's null, or unless the program has "polluted the heap" by circumventing the generic type system.)

If you're going to do this, I'd suggest writing if (t instanceof Integer) instead of doing anything with getClass().

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

Is there anything wrong in the above approach?

Absolutely! If you have to "unmask" the generic type parameter T to do something special, you might as well do it in a separate piece of code, and either pass it on the side the way the class is passed, or require T implement a specific interface that provides the "special" functionality.

Is there an advantage of either techniques above over the other (i.e. passing Class<T> over checking Class type using getClass)?

Passing Class<T> technique has a specific reason behind it - letting you construct objects when you have none to begin with. In other words, it is applicable when you have no object on which to call getClass(), but you want to return an instance of T instead.

Upvotes: 1

Related Questions