Differences in generics declaration in Java

 List<String> v = new ArrayList<String>();

      

I understand that generics help you to declare that ArrayList () is of type String objects. My question is, how does the following differ from the one above?

 List<String> v = new ArrayList();

      

or one that is different from others

List v = new ArrayList<String>();

      

+3


source to share


5 answers


List<String> v = new ArrayList();

      

It is not functionally different. The type parameter on the right side does nothing. It is used as a style and avoids using the Raw type, which is considered a programming error. In fact, it was extended in Java 7, so you can just do this: List<String> v = new ArrayList<>();

and don't have to repeat yourself on the right side.

List v = new ArrayList<String>();

      



A list without a type parameter is called Raw Type. It is generally considered a programming error to declare Raw Type in new code that uses generics. Basically, type checking doesn't happen at all, when you declare it this way, you can put anything in that list.

Java generators are a compile-time check. So it's a compile-time reference type. If your reference is of type Raw List

, it doesn't matter what you put on the right side, this is what the compiler will check.

List<String>

is not really a "list with strings". This is the "List" that I asked the compiler to return errors and / or warn me if I put something in there that is not a string. If you ignore the compiler warnings, then it is quite possible to get stuff there, ta line.

+4


source


public static void main(String[] args) throws Exception {
    List<String> list1 = new ArrayList<String>();
    List<String> list2 = new ArrayList(); //This is equivalent to list1 but with compilation warning
    List list3 = new ArrayList<Integer>(); //This is equivalent to list3 = new ArrayList<Object>()
    //list1.add(new Object()); //does not compile
    //list2.add(new Object()); //does not compile
    list3.add(new Object()); //this is fine
    list1 = list3; //ok, but
    System.out.println(list3.get(0)); // this is fine
    System.out.println(list1.get(0)); //Runtime error: ClassCastException
    //List<Object> list5 = list1; //does not compile        
    List<Object> list5 = list3; //ok
}

      



+1


source


List v = new ArrayList();

      

Before java 5 the list will be declared.

List<String> v = new ArrayList<String>();

      

It uses the generics introduced in java 5. It adds compilation type safety.

List<String> v = new ArrayList<>(); 

      

is just an optimization introduced in java 7. It just simplifies the code while maintaining type safety

+1


source


In the first and third cases ( new ArrayList<String>()

) you are creating an instance ArrayList

that can contain String

instances

In the second case ( new ArrayList()

), you create an instance ArrayList

that can contain instances Object

(these are instances of any type - even combination and match)

In the first and second case ( ArrayList<String> v

) you are declaring an instance ArrayList

that can contain String

instances

In the third case ( ArrayList v

) you are declaring an instance ArrayList

that can contain instances Object

.

The problem with the second case is that if you have to get a "raw" ArrayList

(like an instance of an instance), then it can theoretically do something; not just the instances String

that the users of the declaration expect.

Likewise, in the third case, you create ArrayList

which should contain String

s, but ad users don't know this and may try to put other object instances in it

Note: of course, under the hood, in the JVM, the generic type information is lost, so there is no difference in execution plan, but for type safety the compiler will indicate misuse. This way, there is no need to dynamically check / provide the type of objects put in / out of the list - you can assume they are the correct type because the compiler has provided this

0


source


They all compile and they are all valid. The second case most likely only throws a warning - you won't be able to add anything that isn't a string because of List<String>

. In the third case, you have the opposite problem. You can add things that are not strings but can cause an exception to be thrown at runtime.

0


source







All Articles