0

If I have an ArrayList<Shape>, I'm under the impression that within that list I can store objects of class Shape or objects that are subclasses of Shape.

I've also seen a lot of notation around with things like ArrayList<T> or ArrayList<?>. Are these the same things? A T superclass and all its subclasses can be stored, and the ? is just a placeholder?

Basically, how does something like ArrayList<CLASSNAME> differ from ArrayList<T> where you just have the one letter.

7
  • 1
    That is a little unclear. Commented Sep 29, 2013 at 23:03
  • I'd vote to close, but you probably wouldn't notice. Commented Sep 29, 2013 at 23:04
  • Thanks for the heads up, I'll try to clarify, one second. EDIT: Clarified. Commented Sep 29, 2013 at 23:08
  • T can be anything, ClASSNAME is only one type (and its subs). Commented Sep 29, 2013 at 23:12
  • 1
    @arynaq That's assuming there is actually a class(or interface) named CLASSNAME. If there isn't, then there is not difference between ArrayList<CLASSNAME>, ArrayList<T>, and ArrayList<WarAndPeace_ANovelByLeoTolstoy> - they are all just binding the template argument to a differently named symbol. Commented Sep 29, 2013 at 23:17

3 Answers 3

1

First, the difference is not whether it is one letter as you might think. It is whether T is the name of a generic argument or not. If you declare a method like:

public <T> void method()

as opposed to:

public void method()

or a class like:

public class Whatever<T>

as opposed to:

public class Whatever

then T is a generic argument. You then get to use T anywhere you want as if it were a real class name, and a real class name will be substituted for T at compile time. But this is not the best picture of it, so let's say that the type of T is whatever type was passed to the arguments of type T. So, at any given moment, T has a value that is a real class name.

So, the difference between ArrayList<T> and ArrayList<Shape> is that ArrayList<T> holds objects of type T, whereas ArrayList<Shape> holds objects of type Shape. The trick is that T is whatever type was passed to arguments of type T, so it can vary.

Disclaimer: The type T does not actually change over time. In most cases, the compiler replaces it with Object. However, the compiler is good at hiding that, and it is a good idea to think of T changing.

Sign up to request clarification or add additional context in comments.

1 Comment

This is the best answer so far. Not least because it mentions that the fact that T is a single letter is unimportant. Using a single letter (T or E or whatever) for a type parameter is just a common convention - it's not required by the language.
1

First of all, ArrayList can't reference any subclass of Shape like this:

ArrayList<Shape> blah = new ArrayList<Square>

But you can do it this way:

ArrayList<? extends Shape> blah = new ArrayList<Square>

Polymorphism doesn't work with type parameter. It only works with objects such as:

Collection<String> blah = new ArrayList<String>

But you have to understand the purpose of using T. T is used to declare a type parameter for class and methods.

Such that when you declare a class with parameter T:

 public class ArrayList <T>

T acts as a placeholder when the class is instantiated as object.

So in this case:

 ArrayList<String>

you are replacing T with String in the ArrayList class.

Btw, you aren't suppose to use T as a type for argument. Because T isn't really defined, it is only a placeholder.

Comments

0

You express ArrayList<T> when you're declaring the type / class and ArrayList<String> when you're creating an instance of ArrayList and associate it with the type parameter String.

For example:

// class declaration
public class ArrayList<T> extends ... implements ... {
  ...

// Creating an arraylist of string
ArrayList<String> stringArray = new ArrayList<String>

You can think of generics as a type variable. Hence instead of creating a class which only works with String:

public class MyArray {

  String get(int index) { ... }

}

You can create an array class that works with any arbitrary type

public class MyArray<T> {

  T get(int index) { .. }

}

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.