search
HomeJavajavaTutorialDetailed explanation of Java generics

Detailed explanation of Java generics

Dec 19, 2016 pm 02:58 PM
Generics

  1. Overview
    Before the introduction of generics, Java types were divided into primitive types and complex types, of which complex types were divided into arrays and classes. After the introduction of generics, a complex type can be subdivided into more types.
    For example, the original type List is now subdivided into List, List and other types.
    Note that now List and List are two different types,
    There is no inheritance relationship between them, even if String inherits Object. The following code is illegal
    List ls = new ArrayList();
    List lo = ls;
    The reason for this design is that according to the declaration of lo, the compiler allows you to add to lo Any object (such as Integer), but this object is
    List, which breaks the integrity of the data type.
    Before the introduction of generics, if the method in the class supports multiple data types, the method needs to be overloaded. After the introduction of generics, this problem can be solved
    (polymorphism), and furthermore, multiple parameters can be defined and the relationship between return values.
    For example,
    public void write(Integer i, Integer[] ia);
    public void write(Double d, Double[] da);
    The generic version is
    public void write(T t, T[ ] ta);

    2. Define & use
    The naming style of type parameters is:
    It is recommended that you use concise names as the names of formal type parameters (if possible, a single character). It is best to avoid lowercase letters, which makes it easier to distinguish it from other ordinary
    formal parameters.
    Use T for type, whenever there is no more specific type to distinguish it. This is often seen with generic methods. If there are multiple type parameters, we might use a letter close to T in the alphabet, such as S.
    If a generic function appears in a generic class, it is best to avoid using the same name in the method's type parameters and the class's type parameters to avoid confusion
    . The same goes for inner classes.

    2.1 Define a class with type parameters
    When defining a class with type parameters, in the immediately following the class name, specify the name of one or more type parameters, and you can also specify the type parameters.
    The value range is limited, and multiple type parameters are separated by a, sign.
    After defining the type parameters, you can use the type parameters almost anywhere in the class after the definition position (except static blocks, static properties, and static methods),
    just like using ordinary types.
    Note that the type parameters defined by the parent class cannot be inherited by the subclass.
    public class TestClassDefine , specify the name of one or more type parameters,
    You can also limit the value range of the type parameters, and separate multiple type parameters with a, sign.
    After defining the type parameters, you can use the type parameters anywhere in the method after the definition position, just like using ordinary types.
    For example:
    public T testGenericMethodDefine(T t, S s){
    ...
    }
    Note: The main purpose of defining a method with type parameters is to express multiple parameters and return relationship between values. For example, in the inheritance relationship between T and S in this example, the type of the return value is the same as the value of the first type parameter.
    If you just want to achieve polymorphism, please use wildcards first. See the following section for wildcard content.
    public void testGenericMethodDefine2(List s){
     …
    }
    should be changed to
    public void testGenericMethodDefine2(List> s){
     …
    }

    3. Type Parameter assignment
    When assigning values ​​to type parameters of a class or method, all type parameters are required to be assigned. Otherwise, you will get a compilation error.

    3.1 Assigning type parameters to a class with type parameters
    There are two ways to assign type parameters to a class with type parameters
    First, declare a class variable or instantiate it. For example,
    List list;
    list = new ArrayList;
    When the second inherited class or implements the interface. For example
    public class MyList extends ArrayList implements List {...}

    3.2 Assigning values ​​to methods with type parameters
    When calling a generic method, the compiler automatically assigns values ​​to the type parameters. A compilation error occurs when the assignment cannot be successful. For example
    public T testGenericMethodDefine3(T t, List list){
    ...
    }
    public T testGenericMethodDefine4(List list1, List list2){
    ...
    }

    Number n = null;
    Integer i = null;
    Object o = null;
    testGenericMethodDefine(n, i);//At this time T is Number and S is Integer
    testGenericMethodDefine(o, i);// T is Object, S is Integer

    List list1 = null;
    testGenericMethodDefine3(i, list1)//T is Number at this time

    List list2 = null;
    testGenericMethodDefine4(list1, list2)// Compilation error

    3.3 Wildcard
    In the above two sections, specific values ​​are assigned to type parameters. In addition, undefined values ​​can also be assigned to type parameters. For example
    List> unknownList;
    List extends Number> unknownNumberList;
    List super Integer> unknownBaseLineIntgerList;
    Note: In the Java collection framework, for container classes whose parameter values ​​are of unknown types, they can only be read Among the elements, elements cannot be added to it,
    Because its type is unknown, the compiler cannot identify whether the type of the added element is compatible with the type of the container. The only exception is NULL

    List listString;
    List > unknownList2 = listString;
    unknownList = unknownList2;
    listString = unknownList;//Compilation error

    4. Array generic
    You can use a class with generic parameter values ​​to declare an array, but you cannot create an array
    List [] iListArray;
    new ArrayList[10];//Compile time error

    5. Implementation principle

    5.1. Java generic compile-time technology does not contain generic information at runtime, only instances of Class Contains the definition information of type parameters.
    Generics are implemented through a front-end process called erasure by the Java compiler. You can (basically) think of it as a source-to-source transformation, which converts the generic version into the non-generic version.
    Basically, erasure removes all generic type information. All type information between angle brackets is thrown away, so, for example, a
    List type is converted to List. All references to type variables are replaced by the upper bound of the type variable (usually Object). Also,
    Whenever the resulting code type is incorrect, a conversion to the appropriate type will be inserted.
                                                                                                                                                                                                                  . This means they don't add any time or space overhead, which is nice. Unfortunately, this also means that you can't rely on them for type conversion.

    5.2. A generic class is shared by all its calls
    What is the result printed by the following code?
    List l1 = new ArrayList();
    List l2 = new ArrayList();
    System.out.println(l1.getClass() == l2.getClass()) ;
    Maybe you will say false, but you are wrong. It prints true. Because all instances of a generic class have the same runtime class at runtime, regardless of their actual type parameters.
    In fact, the reason why generics are called generics is because they have the same behavior for all its possible type parameters; the same class can be regarded as many different
    types. As a result, the static variables and methods of the class are also shared among all instances. This is why it is illegal to use type parameters (type parameters belong to specific instances) in static methods or static initialization code, or when declaring and initializing static variables.

    5.3. Casting and instanceof
    Another implication of a generic class being shared by all its instances is that it makes no sense to check whether an instance is a specific type of generic class. I Collection CS = New ArrayList & LT; String & GT; ();
    If (cs instanceofllection & lt; string & gt;) {...} // illegal
    法Collection & LT ; String & gt; cstr = (Collection & LT; String & GT; ) cs;
    Get an unchecked warning because the runtime environment will not do such a check for you.

    6. Generic processing of Class
    After Java 5, Class becomes generic.
    One of the changes in JDK1.5 is that the class java.lang.Class is generic. This is an interesting example of extending generics beyond container classes.
    Now, Class has a type parameter T. You may ask, what does T stand for? It represents the type represented by the Class object. For example, the
    String.class type represents Class, and Serializable.class represents Class.
    This can be used to improve the type safety of your reflected code.
    Specially, because Class's newInstance() method now returns a T, you can get a more precise type when creating objects using reflection.
    For example, suppose you want to write a tool method to perform a database query, given a SQL statement, and return a collection of objects in the database that meet the query conditions
    .
    One method is to explicitly pass a factory object, like the following code:
    interface Factory {
       public T[] make();
    }
    public Collection select(Factory   Collection result = new ArrayList();
                                                                                                                                              use using ’ ’ s ’ use ’ s ’ using jdbc ’ t ’s ’ ‐ ‐ ‐ ‐ dbc */                                          Over JDBC Results */
    t item = Factory.make (); Return result;
    }
    You can Call like this:
    select(new Factory(){
      public EmpInfo make() {
        return new EmpInfo();
        }
        } , “selection string”);
    You can also declare a class EmpInfoFactory to support interface F actory :
    class EmpInfoFactory implements Factory { ...
      public EmpInfo make() { return new EmpInfo();}
    }
    Then call:
    select(getMyEmpInfoFactory(), "selection string");
    This solution The disadvantage is that it requires one of two things: a lengthy anonymous factory class at the call site, or declaring a factory class for each type to be used and passing its object to the call site, which is unnatural.
    Using class type parameter values ​​is very natural and can be used by reflection. Code without generics may be:
    Collection emps = sqlUtility.select(EmpInfo.class, ”select * from emps”); ...
    public static Collection select(Class c, String sqlStatement) {
    Collection result = new ArrayList ();
    /* run sql query using jdbc */
    for ( /* iterate over jdbc results */ ) {
    Object item = c.newInstance();
    /* use reflection and set all of item's fields from sql results +/ Now that Class is generic, we can write:
    Collection emps=sqlUtility.select(EmpInfo.class, ”select * from emps”); ...
    public static Collection select( Classc, String sqlStatement) {
    Collection result = new ArrayList();
    /* run sql query using jdbc */
    for ( /* iterate over jdbc results */ ) {
            T item = c.newInstance(); The collection we want.
    This technique is a very useful trick that has become a widely used idiom in new APIs that handle annotations.

    7. Compatibility of old and new code

    7.1. In order to ensure code compatibility, the following code compiler (javac) allows, type safety is guaranteed by yourself
    List l = new ArrayList();
    List l = new ArrayList();

    7.2. When upgrading your class library to a generic version, use covariant return values ​​with caution.
    For example, the code
    public class Foo {
      public Foo create(){
                                                                    use           using                 using                   use                 use                 use      public Foo create(){
                                                                                                                                """"""" ;
    }
    }
    Be careful with the clients of your library.




    For more articles related to detailed explanation of Java generics, please pay attention to the PHP Chinese website!


Statement
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
How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution?How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution?Mar 17, 2025 pm 05:46 PM

The article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.

How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management?How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management?Mar 17, 2025 pm 05:45 PM

The article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?Mar 17, 2025 pm 05:44 PM

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading?How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading?Mar 17, 2025 pm 05:43 PM

The article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]

How does Java's classloading mechanism work, including different classloaders and their delegation models?How does Java's classloading mechanism work, including different classloaders and their delegation models?Mar 17, 2025 pm 05:35 PM

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.