1

I was wondering if there's a way to, in Java, use a generic type within a generic method without requiring an argument specifying the class type. Here's the normal way of doing it:

public <T> T doSomethingGeneric(Class<T> type, int a) {
    return (T) doSomethingElse(type, a);
}

I would like this as an alternative:

public <T> T doSomethingGeneric(int a) {
    return (T) doSomethingElse(/* some magic with T here */, a);
}

Background: I'm writing utility methods with Hibernate. Here's an example of what I'm actually trying to do, and you can infer how it applies to this problem.

public static <M extends Model> M get(Class<M> type, Serializable id) {
    Session session = newSession();
    Transaction t = session.beginTransaction();
    Object model = null;
    try {
        model = session.get(type, id);
        t.commit();
    } catch (HibernateException ex) {
        t.rollback();
        throw ex;
    }
    return (M) model;
}

Is this possible? If so, how is it done? Thanks!

Blake Beaupain
  • 638
  • 1
  • 6
  • 16
  • 1
    Out of curiosity, why are you writing your own `get()` method and not using [`EntityManager`](http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html)? – Matt Ball Feb 28 '13 at 20:50
  • Because I'm new to Hibernate and didn't know that EntityManager existed. Thanks for the tip. :) – Blake Beaupain Feb 28 '13 at 20:51
  • In that case, I strongly recommend at least skimming the relevant part of the Java EE tutorial: http://docs.oracle.com/javaee/6/tutorial/doc/bnbpy.html – Matt Ball Feb 28 '13 at 20:54

2 Answers2

4

You want to get a Class<T> at runtime to pass to doSomethingElse()? No, that is not possible.

If you describe why doSomethingElse needs a Class<T>, perhaps we could suggest a workaround.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • I'm writing utility methods with Hibernate. Here's an example of what I'm actually trying to do, and you can infer how it applies to this problem: https://gist.github.com/blakeman8192/de57273f472ceaf1b7d8 – Blake Beaupain Feb 28 '13 at 20:42
  • 1
    Yeah, this isn't possible. That's why `Session#get()` needs a `Class` in the first place. – Matt Ball Feb 28 '13 at 20:44
2

This isn't possible: the code of doSomethingGeneric is only compiled once, unlike the instantiation of a template in C++. The type T is erased to Object in the process.

Notice also that (T) will be flagged as an unchecked downcast.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436