Home > Java > javaTutorial > Java--Generics

Java--Generics

巴扎黑
Release: 2017-06-27 09:13:57
Original
1926 people have browsed it

Type parameters

Use when defining a generic class or declaring a variable of a generic class Angle brackets to specify formal type parameters. The relationship between formal type parameters and actual type parameters is similar to the relationship between formal method parameters and actual method parameters, except that type parameters represent types rather than values.

Named type parameters

The recommended naming convention is to use uppercase, single-letter names for type parameters. This differs from the C++ convention (see Appendix A: Comparison with C++ templates), and reflects the assumption that most generic classes will have a small number of type parameters. For common generic patterns, the recommended name is:

K - key, such as a mapped key.
V —— Value, such as the contents of List and Set, or the value in Map.
E ——Exception class.
T —— Generic.

方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。
Copy after login

##1. Why use generics

1. There is no limit to the elements that can be put in. Putting in two different objects may cause exceptions.

2. Throw the object into the collection. The collection loses the state information of the object. The collection only knows that it holds Object, so after taking out the collection elements, it usually Force conversion is also required

2. What are generics

Java's parameterized types are called generics, which allow the program to specify the type of collection elements when creating a collection

3. Generic diamond Syntax

only needs to be followed by a pair of diamond brackets, no generics are required

4. Create a custom class with a generic declaration. When defining a constructor for the class, the constructor name should still be the original class name. Do not add a generic declaration.

5. Derive a subclass from a generic class. When inheriting, you must pass in the actual parameters for the parent class

public class A extends Apple{}

##All methods in it that override the parent class become the corresponding type

You can also pass in no actual parameters

##public class A extends Apple{}

Treat as Object type

6. There is no generic class

No matter what the actual type parameters of generics are, they always have the same class at runtime. No matter which type of actual parameter is passed into the generic type parameter, ( lies in the purpose of the concept of generics in Java, which causes it to only act in the code compilation phase. During the compilation process, After the generic result is correctly verified, the generic related information will be erased. That is to say, the successfully compiled class file does not contain any generic information and will not enter the runtime phase##. #.) For Java, they are still treated as the same class and occupy a memory space in the memory. Therefore, types are not allowed to be used in the declaration and initialization of static methods, static initialization blocks or static variables. Formal parameters

Explanation:

Static variables are shared by all instances of a generic class. For a class declared as MyClass, the method to access the static variables in it is still MyClass.myStaticVar. Regardless of whether the objects are created through new MyClass or new MyClass, they all share a static variable. Assume that type parameters are allowed as types of static variables. Then consider the following situation:

MyClass class1 = new MyClass();

MyClass class2 = new MyClass();

class1.myStaticVar = "hello";

class2.myStaticVar = 5;

Due to the type erasure of the generic system Except (type erasure). myStaticVar is restored to the Object type, and then when class1.myStaticVar= "hello"; is called, the compiler performs forced type conversion, that is, myStaticVar = (String)"hello"; and then when the class2.myStaticVar statement is called, the compiler continues to perform forced type conversion. , myStaticVar = (Integer)Integer.valueOf(5); At this time, myStaticVar is of type String. Of course, this statement will throw a ClassCastException at runtime, so there is a type safety issue. Therefore, the generic system does not allow static variables of a class to use type parameters as variable types.

# Generic classes will not actually be generated in the system, so the generic class cannot be used after the instanceod operator because it does not exist at all!

7. Type wildcard

Note that, If Foo is a subtype of Bar and G is a class or interface with a generic declaration, G is not a subtype of G.

##Assuming that List can be logically regarded as the parent class of List, then a.test(list) will not have an error message , then the question arises, what type is the data when it is retrieved through the getData() method? Integer? Float? Or Object? And due to the uncontrollable order in the programming process, type judgment and forced type conversion must be performed when necessary. Obviously, this contradicts the concept of generics. Therefore, Logically List cannot be regarded as the parent class of List

In order to represent the parent class of various generic collections, you can use type wildcards. The type wildcard is a Question mark, it can match any type:

Type wildcard is generally used? instead of specific type actual parameters. Note, here are type actual parameters, not type parameters! And List is logically the parent class of all List such as List, List##>... etc. From this, we can still define generic methods to fulfill such requirements.

No matter what the real type of the list is, it contains Object

Note: with wildcards only means It is the parent class of various generic collections and cannot add elements to it

We do not know the type of elements in the c collection and cannot add objects to it

7.1 Set the upper limit of wildcards

##Because List is not a subtype of List, a compilation error occurred

This can be recycled Use restricted generic wildcards

7.2 Setting upper limits on type parameters

8. Generic method

define class, The interface does not use type parameters. When defining the method, I want to define

independent generic static method at the same time without considering multi-threading. point, it will only be initialized and called once, there will be no overlapping initialization and incorrect calls, and there will be no situation like reading dirty data in the database, so there will be no code errors in forced type conversion.

The formal parameters defined in the method declaration can only be used in this method.

Unlike classes and interfaces, generics in methods do not need to show the actual type parameters passed in

You must not let the compiler confuse what type you pass in

For example, test a, Collection b>

If you pass in a String type or an Object type, the compiler does not know what type your T is.

Can it be changed to a, Collection b>

Generic method

(in type parameter one section) You have seen that you can make a class generic by adding a list of formal type parameters to its definition. Methods can also be genericized, regardless of whether the class in which they are defined is generic or not.

# Generic classes enforce type constraints across multiple method signatures. In List, the type parameter V appears in the signatures of methods such as get(), add(), contains(), and so on. When you create a variable of type Map, you declare a type constraint between methods. The value you pass to add() will be of the same type as the value returned by get().

#Similarly, you declare a generic method generally because you want to declare a type constraint between multiple parameters of the method. For example, the ifThenElse() method in the following code will return either the second or third argument, depending on the Boolean value of its first argument:

public T ifThenElse(boolean b, T first, T second) {
return b ? first : second;
}

Note that you can call ifThenElse() without explicitly telling the compiler what you want for T value. The compiler doesn't have to be told explicitly what values ​​T will have; it just knows that the values ​​must all be the same. The compiler allows you to call the following code because the compiler can use type inference to deduce that the String substituted for T satisfies all type constraints:

##String s = ifThenElse(b, "a", "b");

##Similarly, you can call:

Integer i = ifThenElse(b, new Integer(1), new Integer(2));

However, compile The following code is not allowed by the compiler because no type would satisfy the required type constraints:

##String s = ifThenElse(b, "pi", new Float( 3.14));

Why did you choose to use a generic method instead of adding type T to the class definition? There are (at least) two cases where this should be done:

#When a generic method is static, class type parameters cannot be used in this case.

When a type constraint on T is truly local to a method, it means that there is no use of the same type T in another method signature of the same class constraint. The signature of a closed type can be simplified by making the type parameters of a generic method local to the method.


Restricted types

Generic methods in the previous screen In the example, the type parameter V is an unconstrained or unrestricted type. Sometimes it is necessary to specify additional constraints on type parameters when the type parameters have not been fully specified.

Consider the example Matrix class, which uses a type parameter V, which is bounded by the Number class:

public class Matrix { ... }

The compiler allows you to create Matrix or Matrix type, but if you try to define a variable of type Matrix, an error will occur. Type parameter V is evaluated to be bounded by Number . In the absence of type restrictions, type parameters are assumed to be restricted by Object. This is why the example in the previous screen, Generic Methods, allows List.get() to return Object when called on a List, even if the compiler doesn't know the type of the type parameter V.

9. The difference between generic methods and type wildcards

If a method If the type of formal parameter (a) or the type of the return value depends on the type of another formal parameter (b), then the type declaration of formal parameter (b) should not use wildcards, and only the type parameter can be considered to be declared in the method signature. , that is, a generic method.

What I understand is that the type wildcard does not need to add or modify the elements in the collection, and it is attached to others rather than others attached to him. Use

Type wildcards can be used to define the type of formal parameters in method signatures or to define the types of variables. Type parameters in generic methods must be explicitly declared in the corresponding method.

10. Wiping and conversion

When assigning an object with generic information to another When adding a variable without generic information, all type information between angle brackets is thrown away.

##When assigning li to List, the compiler will Erase the former's generic information, that is, lose the type information of the elements in the list collection.

Java also allows the list object to be directly assigned to a List variable, so the program can be compiled and passed, but

"unchecked conversion" is issued (the logical parent class directly assigned to the subclass), but the list variable actually refers to the list collection, so when trying to take out the elements in the collection as a String type object, a run will be triggered Exception

11. Generics and arrays

Java generics have a very important design principle---if a piece of code does not raise an "unconverted exception" warning when compiling, the program will not cause a ClassCastException exception. For this reason, The type of all array elements cannot contain type variables or type parameters, unless it is an unlimited type wildcard, but the element type can be declared to contain an array of type variables or type parameters

Assuming it can pass, no warning will be caused, but an exception will be thrown

Change Into the following format:

The first line will have an "unchecked conversion" warning, and the last line will also throw an exception

Create unlimited wildcards Generic array

#Compilation will not issue any warnings, but an exception will be thrown at runtime because the program needs to force the first collection element of the first array element of lsa Convert to String type, so the program should use the instanceof operator to ensure its data type

Similarly, creating an array object whose element type is a type variable will also cause compilation Error

T[] makeArray(Collection coll)

{ return new T[cool.size()]

}

The type variable does not exist at runtime and the compiler cannot determine what the actual type is

The above is the detailed content of Java--Generics. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template