10

Why this is wrong:

    Class<? extends Number> type = Integer.class;
    ArrayList<type> = new ArrayList<>();

?

Is there no way to instantiate a class of a specific type given a class object?


Obviously I would never do that directly, that is just an example to show what is needed. In the actual code I need I don't know the name of the type. For example

    public void createAList(Class<? extends Number> type)  
{
    ArrayList<type> toReturn = new ArrayList<>();
    return toReturn;
}

7 Answers 7

9
<T extends Number> ArrayList<T> createAList(Class<T> type)  
{
    ArrayList<T> toReturn = new ArrayList<>();
    return toReturn;
}


ArrayList<Integer> intList = createAList(Integer.class);
Sign up to request clarification or add additional context in comments.

4 Comments

Whoa, that did the trick! THe only thing I am not clear is why it works. Do you have any links that explain this in great excruciating detail?
@CarrKnight This answer subtly shows that such a method is totally pointless. Notice that type isn't even used in its body.
yes, but again, this is a simplifying example for stack-overflow. I use the type arguments to create a couple of instances and return them in a "list".
@CarrKnight Then that's a much different question from what you've posted. See my answer to the question in its current form.
4

That's not how you use generics. You don't use a Class object, you use the class name directly in your code.

ArrayList<Integer> = new ArrayList<>();

2 Comments

Thank you! But I am interested in the case where I don't know the name of the class. But I do have that information within the object Class
Your edited question makes it clearer what you want. If you have the Class object, then use @irreputable's answer.
3

Feel the difference between java Class (which actually generic too) object and class name.

You should use class name specifying generic type.

ArrayList<Number> = new ArrayList<>();
// ArrayList<Number.class> = new ArrayList<>(); <- WRONG

UPD:

Use this approach if you'll know type only in runtime:

public <T extends Number> void createAList(Class<T> type) {
    ArrayList<T> toReturn = new ArrayList<>();
    return toReturn;
}

Comments

2

An ArrayList<> has to have a specific type it holds . You can put objects of that type or any sub-type in it though.

So use

List<Number> = new ArrayList<Number>();

and you can put Integers in it

Notice how I used the interface on the left and the class on the right of the equal sign. That's a best practice sort of thing.

If you want a list that will just hold Integer (as per your example) the answer by @irreputable is your best bet. This answer will hold Integer but not just Integer.

1 Comment

Thank you! But I am interested in the case where I don't know the name of the class. But I do have that information within the object Class. See If my edit made it any clearer
1

Taken literally, the other answers' suggestions of how to implement createAList are ignoring something important: due to type erasure, such a method is pointless.

Given you want a List<? extends Number>, you can just write this:

List<? extends Number> lst = new ArrayList<>();

If you just wanted a List<?>, you could write:

List<?> lst = new ArrayList<>();

If you were in the scope of a type parameter T and wanted a List<T>, you could write:

List<T> lst = new ArrayList<>();

Notice that a Class object has nothing to do with these constructor calls, just like the methods in the other answers. That's because at runtime, the ArrayList instance doesn't know or care about whatever generic type its references had at runtime.

Comments

1

You don't even need to pass in an argument:

public <T extends Number> ArrayList<T> createAList () {
    return new ArrayList<T>();
}

Though you may need to explicitly specify the type parameter when calling:

ArrayList<Integer> intList = this.<Integer>createAList();

Comments

0
ArrayList<type> = new ArrayList<>();

this line is wrong. First, you missed identifier (variable name) here; Second, you mixed the concepts of "type" and "class". You can delcare

ArrayList<Integer> list = new ArrayList<>();

But according to yours, type = Integer.class. Obviously, Integer is not equivalent to Integer.class. Similarly you can't have Integer.class i = 1; The former one is a "type", the second one is a "Class" object.

You can create a generic method:

public <T extends Number> List<T> createAList (Class<T> type) {
    return new ArrayList<T>();
}

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.