1

Previously, I wrote a method for a specific entity class called Address and here's the code :

private List<AddLuceneWork> buildAddLuceneWorks(List<Address> addresses) {
    List<AddLuceneWork> addWorks = new LinkedList<>();
    session = em.unwrap(Session.class);
    searchIntegrator = ContextHelper.getSearchintegrator(session);
    entityIndexBinding = searchIntegrator
            .getIndexBindings()
            .get(Address.class);  // specific type
    // ...
    return addWorks;
}

And now, I want to make the input to be generic, so that no matter what entity can be processed. But I didn't use generic type before and I don't know how to use it properly :

private <T> List<AddLuceneWork> buildAddLuceneWorks(List<T> entities) {
    List<AddLuceneWork> addWorks = new LinkedList<>();
    session = em.unwrap(Session.class);
    searchIntegrator = ContextHelper.getSearchintegrator(session);
    entityIndexBinding = searchIntegrator
            .getIndexBindings()
            .get(Address.class);  // <- how to change it to generic ?
    // ...
    return addWorks;
}

I tried the following, but they didn't work :

  • .get(T);
  • .get(T.class);
  • .get(clazz.getClass()); where Class<T> clazz = null;
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
Mincong Huang
  • 5,284
  • 8
  • 39
  • 62

1 Answers1

4

Due to Type Erasure your code at Runtime is actually

private List buildAddLuceneWorks(List entities) {

Such that it cannot work, you need to add an additional parameter of type Class to provide the expected type explicitly like this:

private <T> List<AddLuceneWork> buildAddLuceneWorks(List<T> entities, Class<T> clazz) {

Then get(Address.class) will then be get(clazz)

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • Thanks Nicolas. I'll keep learning how type erasure works. By the way, is there any method to keep the param generic, without using the second parameter ? Such as `List> entities` ? – Mincong Huang Jun 06 '16 at 10:00
  • You switch from a list of object T to a List of Class, it sounds to be totally different from your initial intention but if it is fine with your needs why not? – Nicolas Filotto Jun 06 '16 at 10:09
  • Ah, I can't. I should load all entities and `List>` just loads all the class types... You're right, they're totally different. I'll use your proposition. – Mincong Huang Jun 06 '16 at 10:17
  • 1
    the best you can do is to get the class of an element at runtime but it can be error prone if you have class of different types like A and B that both extends C, your expected type is C and in your list you have an instance of A and B it will then use as class either A or B depending on the reference element which is not what you want – Nicolas Filotto Jun 06 '16 at 10:32