[Reprinted] Java generic concise tutorial

Source: Internet
Author: User

This article is from Java generics quick tutorialArticleThe translation comes from the IT comment on the concise Java generic tutorial. The content is as follows:

Generics are a feature introduced in Java SE 5.0. Since the emergence of this language feature for many years, I believe that almost all JavaProgramNot only have you heard about it, but you have also used it. Java generic tutorials are free, not free, and there are many. The best teaching materials I have ever met are:

The Java tutorial
Java generics and collections, by Maurice naftalin and Philip wadler
Tive Java Chinese version (2nd), by Joshua Bloch.

Despite so many rich materials, I sometimes feel that many programmers still do not quite understand the functions and significance of Java generics. This is why I want to use the simplest form to summarize the basic knowledge of Java generics that programmers need to know.

Motivation for Java generics

The simplest way to Understand Java generics is to look at it as a convenient syntax, which can save some java type conversion (casting) operations:

 
List <Apple> box =...; Apple = box. Get (0 );

The aboveCodeIt is clear that box is a list containing Apple objects. The get method returns an apple object instance, which does not require type conversion. No generics. The code above needs to be written as follows:

 
List box =...; Apple = (Apple) box. Get (0 );

Obviously, the main benefit of generics is that the compiler retains the type information of parameters, performs type checks, and performs type conversion operations: the compiler ensures that these types of conversions are absolutely correct.

Compared with dependent programmers, it is difficult to debug and solve object types and execute type conversion. the compiler can help programmers forcibly perform a large number of type checks during compilation, an error is found.

Generic Components

The structure of generics introduces the concept of a type variable. According to the Java language specification, type variables are unlimited identifiers, produced in the following situations:

Generic class declaration

Generic interface declaration

Generic method declaration

Constructor Declaration

Generic classes and interfaces

If a class or interface has one or more type variables, it is generic. Type variables are defined by Angle brackets and placed behind the class or Interface Name:

 
Public interface list <t> extends collection <t> {...}

Simply put, the role played by a type variable is like a parameter, which provides information to the compiler for Type checks.

Many classes in the Java class library, such as the generic modification of the entire collection framework. For example, the list interface we used in the first code above is a generic class. In that code, box is a list <Apple> object, which is an instance of class implementation with a list interface with an apple type variable. The compiler uses this type variable parameter to automatically convert the type when the get method is called and an apple object is returned.

In fact, this new generic mark, or the get method in this list interface, is like this:

 
T get (INT index );

The get method actually returns an object of type T, and T is a type variable in the list <t> declaration.

Constructor)

Very similar. If methods and constructors declare one or more type variables, they can also be generic.

 
Public static <t> T getfirst (list <t> List)

This method will accept a list <t> type parameter and return a T type object.

Example

You can use both the generic classes provided by the Java class library and your own generic classes.

Type-safe data writing...

The following code is an example. We created a list <string> instance and loaded some data:

 
List <string> STR = new arraylist <string> (); Str. Add ("hello"); Str. Add ("world .");

If we try to mount another object in list <string>, the compiler will prompt an error:

 
Str. Add (1); // cannot be compiled

Type-safe data reading...

When we use the list <string> object, it always ensures that we get a String object:

 
String mystring = Str. Get (0 );

Traversal

Many classes in the class library, such as iterator <t>, have enhanced functions and are generic. The iterator () method in the list <t> interface now returns iterator <t>, and the object returned by its T next () method does not need to be converted to a type, you can directly obtain the correct type.

For (iterator <string> iter = Str. iterator (); ITER. hasnext ();) {string S = ITER. next (); system. out. print (s );}

Use foreach

The "for each" syntax also benefits from generics. The preceding code can be written as follows:

 
For (string S: Str) {system. Out. Print (s );}

This is easy to read and maintain.

Autoboxing and autounboxing)

When Java generics are used, the autoboxing and autounboxing features are automatically used, just like the following code:

List <integer> ints = new arraylist <integer> (); ints. add (0); ints. add (1); int sum = 0; For (int I: ints) {sum + = I ;}

However, what you need to understand is that encapsulation and unblocking will cause performance loss, and generic usage should be cautious.

Child type

In Java, similar to other languages with object-oriented types, the type hierarchy can be designed as follows:

In Java, the child type of type T can be either an extension of type T or a direct or non-direct implementation of type T (if T is an interface ). Because "Become a child type of a certain type" is a transfer relationship, if type A is a child type of B and B is a child type of C, then A is also a child type of C. In the figure above:

Fujiapple (Fuji apple) is a child type of Apple

Apple is a child type of fruit (fruit)

Fujiapple (Fuji apple) is a child type of fruit (fruit)

All Java types are object-type subtypes.

Any sub-type A of type B can be assigned a declaration of type B:

Apple A =...; fruit F =;

Subtypes of generic types

If an apple object instance can be assigned a fruit object declaration, as shown above, what is the relationship between list <Apple> and a list <fruit>? More general. If type A is a child type of type B, what is the relationship between C <A> and C <B>?

The answer is unexpected: It doesn't matter. In more general terms, generic types have no relationship with whether they are child types.

This means that the following code is invalid:

 
List <Apple> apples =...; List <fruit> fruits = apples;

Why? Why can't an apple be a fruit?

In some cases, this can be true, but not in the status and operation of type (class) encapsulation. What happens if I treat a box of apples as a box of fruit?

List <Apple> apples =...; List <fruit> fruits = apples; fruits. Add (New strawberry ());

If so, we can mount different fruit types in the list, which is absolutely not allowed.

Another method will give you a more intuitive understanding: a box of fruit is not a box of apples, because it may be a box of another fruit, such as a strawberry (Child type ).

Is this a concern?

It should not be a big problem. The biggest surprising reason for programmers is the inconsistent usage of arrays and generic types. For generic types, there is no relationship between them and their subtypes. Arrays are related to child types. If type A is a child type of type B, A [] is a child type of B:

 
Apple [] apples =...; fruit [] fruits = apples;

Please wait! If we put the problem exposed in the previous discussion here, we can still add the strawberrie (Strawberry) object to an apple array:

Apple [] apples = new Apple [1]; fruit [] fruits = apples; fruits [0] = new strawberry ();

In this way, the image can be compiled, but an arraystoreexception is thrown during runtime. In terms of data storage operations, Java runtime needs to check the compatibility of data types. This kind of check obviously brings some performance problems. You need to understand this.

Again, generics are safer to use and can "correct" the defects in this type in the Java array.

Now you may be wondering why there is a relationship between this type and the child type on the array. I will give you the answer in the book Java generics and collections: if they are irrelevant, you cannot pass an array of unknown objects into a method (instead of encapsulating them into object [] Every time), just like the following:

 
Void sort (object [] O );

After the appearance of generics, the array's personality is no longer necessary for use (we will talk about this in the following part). In fact, we should avoid using it.

Wildcard

In the previous sections of this article, we have discussed the non-relevance of subtypes of generic types. However, sometimes we want to use generic types as normal:

Reference a generic object

Styling a reference to a generic object downward

Reference a generic object

For example, if we have a lot of boxes and each box contains different fruits, we need to find a way to process any box of fruit in general. In more general terms, a is a sub-type of B. We need to find a way to assign a C <A> type instance to a C <B> type declaration.

To do this, we need to use an extension declaration with a wildcard, as in the following example:

 
List <Apple> apples = new arraylist <Apple> (); List <? Extends fruit> fruits = apples;

"? Extends is a subtype correlation of generic types. It becomes a reality: Apple is a child type of fruit, and list <Apple> is list <? Child type of extends fruit>.

Styling a reference to a generic object downward

Now I will introduce another wildcard :? Super. If type B is a super type (parent type) of type A, C <B> is C <? Sub-type of super a>:

List <fruit> fruits = new arraylist <fruit> (); List <? Super Apple> = fruits;

Why can I use wildcard characters?

The principle is already quite clear: how can we use this new syntax structure?

? Extends

Let's take a look at the example used in the second part, where we talked about the subtype relevance of the Java array:

 
Apple [] apples = new Apple [1]; fruit [] fruits = apples; fruits [0] = new strawberry ();

As we can see, when you add a strawberry object to an apple object array declared as a fruit array, the code can be compiled, but an exception is thrown at runtime.

Now we can use wildcards to convert related code into generics: because Apple is a subclass of fruit, we use? Extends wildcard, so that you can assign a list <Apple> object definition to a list <? On the declaration of extends fruit>:

 
List <Apple> apples = new arraylist <Apple> (); List <? Extends fruit> fruits = apples; fruits. Add (New strawberry ());

This time, the Code cannot be compiled! The Java compiler will prevent you from adding strawberry to a fruit list. During compilation, we can detect errors. during runtime, we do not need to check to ensure that incompatible types are added to the list. Even if you add a fruit object to the list:

 
Fruits. Add (new fruit ());

You cannot do this. In fact, you cannot use one? Write any value in the data structure of extends.

The reason is very simple. You can think like this? The extends t wildcard tells the compiler that we are processing the child type of A type T, but we do not know what the child type is. We are not allowed to add any data of this type to ensure data type security. On the other hand, we know that no matter what type it is, it is always a child type of type T. When we read data, we can ensure that the data obtained is a T-type instance:

 
Fruit get = fruits. Get (0 );

? Super

Use? What is super wildcard? Let's first look at this:

 
List <fruit> fruits = new arraylist <fruit> (); List <? Super Apple> = fruits;

We can see that fruits points to a list containing a certain supertype of apple. Similarly, we do not know what superclasses are, but we know that Apple and any apple subclass are compatible with their types. Since this unknown type is apple and it is also the superclass of greenapple, we can write:

Fruits. Add (new Apple (); fruits. Add (New greenapple ());

If we want to add apple's superclass to it, the compiler will warn you:

 
Fruits. Add (new fruit (); fruits. Add (new object ());

Because we don't know what kind of superclass it is, all such instances are not allowed to join.

What if I get data from this type? The result shows that you can only retrieve the object instance: because we don't know what the superclass is, the only thing the compiler can ensure is that it is an object, because the object is a superclass of any Java type.

Access principles and Pecs rules

Summary? Extends and? The features of the Super wildcard can be concluded as follows:

If you want to obtain data from a data type, use? Extends wildcard

If you want to write an object into a data structure, use? Super wildcard

If you want to store and retrieve data, do not use wildcards.

This is the access principle that Maurice naftalin mentioned in his book "Java generics and Collections" and the PECS law that Joshua Bloch mentioned in his book "valid Java.

Bloch warned that this pecs refers to "producer extends, consumer super", which is easier to remember and use.

From: It comments of external journals

Note: This article is reposted at http://sd.csdn.net/a/20110603/299216.html, which has been deleted and modified.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.