3

Is there any way by which we can create specific instance of generic type at runtime?

For example.

Cacheable instance = getCacheable(someInput);

getCacheble method will return me the instance of Cacheable. So it can be any class implementing Cacheable.for e.g. Customer,Product etc.Now I want to create a list of specific type returned by getCacheable as below.Is that possible? If yes how to do that?

List<? extends Cacheable> cacheList = new ArrayList<>();

I want to create ArrayList<Product> or ArrayList<Customer> based on the instance returned by getCacheable method.

1
  • 1
    Due to erasure this is somewhat irrational because a List doesn't have a type at run time. Generics are for compile time checks. So the real answer depends on your actual use case. Why do you want compile time checks and how? At run time you can put anything in any list and generics just serve as a gatekeeper. Commented Dec 11, 2013 at 23:17

4 Answers 4

6

You can do this:

Cacheable instance = getCacheable(someInput);
List<? extends Cacheable> l = new ArrayList<>();
l = Collections.checkedList(l, instance.getClass());

Because of type erasure, all information accessible at compile time is lost at runtime. The checkedList method will ensure that your list will receive only instances of the class of instance variable.

UPDATE: You can do this also:

public static <T extends Cacheable> MyOwnCustomGeneric<T> createMyOwnCustomGeneric(Class<T> type) {
    return new MyOwnCustomGeneric<T>();
}

// ...
IMyOwnCustomGeneric foo = createMyOwnCustomGeneric(instance.getClass());
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer.The prob is I am not actually using List, its my own custom generic class.I took List as an example to simplify the prob statement.
@Jai Is you own custom generic class is a Collection (docs.oracle.com/javase/7/docs/api/java/util/Collection.html) ? If so, you can use checkedCollection instead of checkedList.
No Alex.Its not collection. I wanted to avoid the instance of check here, but I think its not possible.
@Jai I have added an alternative if you want to avoid instance of check.
@Alex, i have actually proposed this in my answer before your update when i noticed that you have mentioned the built-in approach :)
|
2

Use generic helper function:

public static <T extends Cacheable>ArrayList<T> createList(Class<T> claz)
{
       return new ArrayList<>();
}

ArrayList<? extends Cacheable>alist = createList(instance.getClass());

5 Comments

Note that the parameter claz is not used and can be removed.
@PaulBellora, isn't it required to infer the type from the instance's own type. I understand that as alist has the type ArrayList<? extends Cacheable> it is not needed
Type inference is something that happens at compile time. If it fails type arguments can be manually specified with e.g. MyClass.<Product>createList(). But considering that generic types have been erased at runtime, what the OP is asking for doesn't make sense. createList(instance.getClass()) can be reduced to new ArrayList<Cacheable>() because at runtime it's all just ArrayList.
@PaulBellora, that is not just that, with ArrayList<? extends Cacheble>: we can't actually add an element to the list. Not even it will allow us to add element of type Cacheble itself. So yes, it wasn't making sense to me either :)
The diamond operator isn't supported by Java 6 though. (Agreed 6 is a long time ago)
0
if (instance instanceof Product) { 
   // create ArrayList<Product>; 
} else { 
   // create ArrayList<Customer>;
}

This is not really general and dynamic though.

1 Comment

But I like Alex's answer more.
0

The only way to do it is by switching on the type of instance but there isn't much you can do with it:

List<? extends Cacheable> cacheList = null;
if (instance instanceof Product)
  cacheList = new ArrayList<Product>();
// etc

But what can you do with this list? You cannot add anything to it. Maybe you add items to it while creating it, but that is probably not the use case since it is a cache list.

If you need to add items to it later, see this answer is the right approach.

If you are not going add items later, it does not matter if the type is List<Cacheable> or List<? extends Cacheable>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.