This question already has answers here:
Java Raw Type and generics interaction
(2 answers)
Closed 6 years ago.
What is the difference between
List<String> list = new ArrayList();
and
List<String> list = new ArrayList<>();
?
In the first case, the IDE highlights it and says "Unchecked assignment", but they seem to behave exactly the same.
The type of each entry in the ArrayList has not been specified, only the List, hence why the Unchecked assignment warning. You should explicitly state it in one of two ways...
List<String> list = new ArrayList<String>();
Or, you can abbreviate that now (since Java 7) to...
List<String> list = new ArrayList<>();
...and the compiler will then be able to implicitly pick up the type from the List's type designation.
No difference, java compiler could figure out the type, but better add the inferred type argument:
List<String> list = new ArrayList<String>();
Related
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 2 years ago.
What's the difference between the following lines:
ArrayList list = new ArrayList();
ArrayList<String> list = new ArrayList();
ArrayList<String> list = new ArrayList<String>();
I just started learning about collections and data structures from the HeadFirstJava book and am a bit confused since I see people use all three of the examples above while researching.
The first and second line use raw types.
A raw type is a type that is used without type parameters, even though the base class has a type argument.
Raw types exist only for backwards compatibility with ancient (pre-Java 5) code and should never be used in new code at all. The rules about raw types are weird and unintuitive.
The third one is correct, but can be written in a shorter way like this:
ArrayList<String> list = new ArrayList<>();
This one will let the compiler "guess" what is meant to go into the <>.
This question already has answers here:
Initializing arraylist without object type - JAVA [duplicate]
(2 answers)
Closed 3 years ago.
What is the difference between ArrayList<String> animals = new ArrayList<>() and ArrayList<String> animals = new ArrayList<String>()? I'm confused.
Both are actually the same.
When generics were introduced in Java 5, we had to use
ArrayList<String> animals = new ArrayList<String>();
When Java 7 arrived, one of the featured it delivered was the support of the shorter form:
ArrayList<String> animals = new ArrayList<>();
So if you're on Java 7+ you can use both (of course the shorter form is preferred)
there is no difference , if you use java 1.6 or older versions you should write your code like this
ArrayList<String> animals = new ArrayList<String>();
but after java 1.6 it will infer the type and you can write your code with just a diamond <>.
ArrayList<String> animals = new ArrayList<>();
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 7 years ago.
I can't understand the difference between the two code snippets below. Can someone help me with a simple explanation?
When we should use them?
If someone can help me with a simple explanation I'll appreciate.
//1
List list1=new ArrayList();
for(Object obj:list1){}
//2
List<Object>list2=new ArrayList();
for(Object obj:list2){}
Generics comes with Java5 and the main idea of this is to avoid the well know exception ClassCastException. In your example, before Java5 we were used to iterate collections of object and casting it's on runtime, so the exception mentioned above happened very often.
With Generics this kind of runtime exception became a compile time exception and you are be able to realized these errors early. In your example you can choice if you want to handle this situation as a runtime error (option 1) or compilation error (option 2) and realize how easier is to handle it in the option 2.
Generics is more than just implicit or explicit declaration, you should take a look at this tutorial.
List and List<Object> are similar (in that you can add any type to them) but different things .
List is a raw type and i can say List l =new ArrayList<Integer>() or List l =new ArrayList().
But for List<Object> ,i can only assign List implementation of Object type. I can't say List<Object> l = new ArrayList<Integer>(); .
This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 8 years ago.
Hi I have not a clear idea between,
List<String> list = new ArrayList<String>();
and
ArrayList<String> list = new ArrayList<String>();
List<String> list = new ArrayList<String>();
Creates a List of type string, and the list can be potentially typecast into any other type of list. This is called decoupling. You are decoupling your code from a specific implementation of the interface. The advantages it provides, is when writing large amounts of code, you can switch between types of lists to suit your preferences (speed, memory etc), as all of your code, can treat your list as just type List. You can also pass a List as parameters and returns List from functions. And later on if you are not happy with the ArrayList, you just change that one line of code
List<String> list = new ArrayList<String>(); // old code
List<String> list = new LinkedList<String>(); // new code
// The rest of the code doesnt need changing
...
list = getList();
...
public List<String> getList() {
List<String> temporaryList;
...
return temporaryList;
}
public void changeList(List<string> localListVariable) {}
And your program will behave as expected.
On the other hand,
ArrayList<String> list = new ArrayList<String>();
Creates an ArrayList of String types and it cannot be used as any other kind of List (Vector,LinkedList etc). Therefore it is bound by the methods available to an ArrayList.
If you now want to change the type of list used, you will have to change all function parameters and return types and so on throughout your program (wherever you have had to create an ArrayList<String> to work with your variable).
List<String> is a superclass (or could be a valid interface) of ArrayList<String>. Assigning an instance of ArrayList<String> to a List<String> variable is allowed. It's somehow a form of dynamic casting. When accessing List<String> list, only methods accessible with List<String> could be used; and those from ArrayList<String> would be hidden despite the object being an instance of ArrayList<String>.
With respect to the instance in memory that you obtain there is no difference. However, it is considered a good practice to Program to Interfaces (see e.g. What does it mean to "program to an interface"?). Many Java APIs are defined in terms of interfaces, i.e. the functionality will work independently on which implementation of a particular interface you use. This aids code clarity and quality and reduces the probability of bugs which arise from relying on some particular properties of an implementation class (unless these properties are really important).
In both the cases, you create object of ArrayList. But List<String> list = new ArrayList<String>(); will refer the object by using a reference of List<String> whereas ArrayList<String> list = new ArrayList<String>(); will refer the object by using a reference variable of type ArrayList<String>.
For example, you can call a method named ensureCapacity by using a reference of ArrayList<String>, but you can't do that using a reference of List<String>.
The following will compile:
ArrayList<String> list = new ArrayList<String>();
list.ensureCapacity(10); // This will work
The following won't compile:
List<String> list = new ArrayList<String>();
list.ensureCapacity(10); // This will not compile
ArrayList creates an object of type ArrayList and List creates an object of type List, ArrayLists underlying interface. Search the javadocs if you dont know what interfaces are.
This question already has answers here:
What's the difference between unbounded wildcard type List<?> and raw type List?
(4 answers)
Closed 4 years ago.
I've read alot about this, and I know that:
List<Object> listOfObject = new ArrayList<TYPE>(); // (0)
//can only work for TYPE == Object.
//if TYPE extends Object (and thus objects of type TYPE are Objects),
//this is not the same with Lists: List<Type> is not a List<Object>
Now I've read that the following is ok:
List undefinedList = new ArrayList<TYPE>(); // (1)
//works for ANY type (except for primitives)
And
List<?> wildcardList = new ArrayList<TYPE>(); // (2)
//also works for ANY type (except for primitives)
Then:
List undefinedlist = new ArrayList(); //no TYPE specified
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS
However:
List<?> wildcardList = new ArrayList<TYPE>(); //TYPE specified
wildcardList.add(new TYPE(...)); //COMPILER ERROR
example:
List<?> wildcardList = new ArrayList<String>(); //TYPE specified
wildcardList.add(new String("string")); //COMPILER ERROR: The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (String)
I do understand why you can't add anything to the wildcardList, since its type can be anything. However, why can you add to the undefinedList??
They seem the same & show the same behavior, given (1) and (2).
List undefinedList and List<?> wildcardList are not the same, as you discovered yourself. The first is raw type and the second is unbounded wildcard.
Use the unbounded wildcard if you want to use a generic type but you don’t know or care what the actual type parameter is. You cannot put anything (except null) into this list, and all you know about the element you get out of it is that they extend Object (actually List<?> is the same as List<? extends Object>). Unbounded wildcards are useful, because if you would declare something naively as List<Object>, you could not assign for example List<String> to it, while you can assign a List<String> to a List<?>
You should (almost) never have the need to use raw types, they are available only for compatibility with code written before Java 5.
List<?> is read as a list of some unknown type . As a programmer you can not make any assumption of what type that is and you can not put anything into such a collection other than null . But you can be rest assured that your list is type safe since the compiler will guarantee type safety for you .
List is basically called raw type . That is to say that it has opted out of type safety guaranteed by the compiler . So you can put elements of any type into that List destroying its invariants . Don't code with raw types any more . They are basically supported for backward compatibility because java was already in the second decade of development when Sun brought generics to the table and a awful lot of code was written using raw types and those programs would otherwise break.
List means that this is a list of unknown type - as such you wouldnt use it at creation time (as in your example), you'd typically use it as a method parameter. Unbound wildcards are only really useful when used as parameters in methods, such as:
public void printList(List<?> items)
This could iterate of a list of (any) unknown items. In this case List items would achieve the same purpose, but client would probably get a warning.
If you had the following:
public void printList(List<Object> items)
Then only a list of Object could be processed - not a list Strings, Integers etc. Only Objects.
Take a look at Unbounded Wildcards - it explains its pretty well
The "undefined" List contain list of type Object which is the father of all types and hence the List is not type-safe(is interconvertible)
which is why this:
List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS
well.. works!
Basically, ? in the following
List<?> wildcardList = new ArrayList<TYPE>();
means some unknown (particular) type. So, it doesn't allow you add something like String, or Integer to a list of some unknown type, because generics is meant to be type-safe.
While, in the following
List<Object> listOfObject = new ArrayList<TYPE>();
you can add anything to it because everything is an Object in Java. So it's type-safe.
And also with the following
List undefinedList = new ArrayList<TYPE>();
you are telling the compiler that you don't want to use generics there. Which means every method you invoke on undefinedList will be non-generic since you have decided to use the raw List. Non-generic versions of all the containers in the collection framework were written to work for Object (which any object in Java is).
The List<?> type is generic: whatever type you put in place of the question mark will be used in the methods of the list. So you can do list.add(item) and it will only allow you to put in a String if you created a List<String>. Type-safety first.
List<String> list = new List<String>();
list.add("A"); // <-- Correct
list.add((Integer)10); // <-- Error, it is a List of Strings
The List on the other hand allows any Object to be put in there. So you can make a List, put a Giraffe in there, and later a Squid. It does not care, and could be a source of programming errors if you expect only Giraffe objects to be in there.
List list = new List();
list.add("A"); // <-- Allowed
list.add((Integer)10); // <-- Also allowed,
// but now the list contains not only strings