What is a generic? The basic principle and the advantages of using generics.

1. What is a generic?

The generic interface concept is further extended, "generic" literally means that a wide range of types. Classes, interfaces and methods can be applied to a very wide range of code types, data type code is no longer capable of operating with their bound together, the same set of codes may be used for a variety of data types, so that not only the code reuse, to reduce coupling , but also improves readability and security code. Talk up the advantages of abstraction, we look at an actual example.

2. The first look at a simple example of generic

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:14
 */

public class Pair<T> {
    T one;
    T two;

    public Pair(T one, T two) {
        this.one = one;
        this.two = two;
    }

    public T getOne() {
        return one;
    }

    public T getTwo() {
        return two;
    }
}

Observation and ordinary class differences:

  1. Back one more class name<T>
  2. one and type two are T

T 3. So what is it?

T represents a type parameter

Is a generic type parameter, data processing type is not fixed, but may be passed as a parameter.

Now we know, the generic type as a parameter to use.

4. How to use generics and type as an argument it?

The following code: We were new three Pair object, passing in the type parameter (Integer, Character, String) of different types.

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:22
 */

public class Test {
    public static void main(String[] args) {
        
        Pair<Integer> pairInteger =  new Pair<Integer>(1,2);
        int one1 = pairInteger.getOne();
        int two1 = pairInteger.getTwo();
        System.out.println("one:"+one1+",two:"+two1);

        Pair<Character> pairCharacter  =  new Pair<Character>('一','二');
        char one2 = pairCharacter.getOne();
        char two2 = pairCharacter.getTwo();
        System.out.println("one:"+one2+",two:"+two2);

        Pair<String> pairString  =  new Pair<String>("I","II");
        String one3 = pairString.getOne();
        String two3 = pairString.getTwo();
        System.out.println("one:"+one3+",two:"+two3);
    }
}

The results are as follows:

one:1,two:2
one:一,two:二
one:I,two:II

Of course, we can not just pass a type parameter, can also pass multiple type parameters. A plurality of types of parameters with a comma "," separated. As in the following example:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:37
 */

public class PairTwo <U,V> {
    U one;
    V two;

    public PairTwo(U one, V two) {
        this.one = one;
        this.two = two;
    }

    public U getOne() {
        return one;
    }

    public V getTwo() {
        return two;
    }
}

So to use:

PairTwo<String,Integer> pairTwo = new PairTwo<>("牛牛",20);

Note: Since the beginning of Java 7, the type of support behind parameters omitted, so that the writing simpler.

The basic principle of generics

Generic type argument in the end is what? Why we must define the type parameters? Define the general category, it is also possible to directly use the Object. Pair class as before we can write:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:44
 */

public class PairObject {
    Object one;
    Object two;

    public PairObject(Object one, Object two) {
        this.one = one;
        this.two = two;
    }

    public Object getOne() {
        return one;
    }

    public Object getTwo() {
        return two;
    }
}

Then such use, the effect is the same:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:46
 */

public class TestPairObject {
    public static void main(String[] args) {
        PairObject pairObject1 = new PairObject(1,2);
        int one1 =(int)pairObject1.getOne();
        int two1 =(int)pairObject1.getTwo();
        System.out.println("one:"+one1+",two:"+two1);

        PairObject pairObject2 = new PairObject("yi","er");
        String one2 =(String)pairObject2.getOne();
        String two2 =(String)pairObject2.getTwo();
        System.out.println("one:"+one2+",two:"+two2);
    }
}

Output:

one:1,two:2
one:yi,two:er

We can see that indeed our use Object + cast also achieve the same result. In fact, the internal principles of our Java generics is the case.

We use JAD tools to decompile the results of our Pair.class and Test.class are as follows:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Pair.java

package genericity.demo;
public class Pair
{
    public Pair(Object obj, Object obj1)
    {
        one = obj;
        two = obj1;
    }
    public Object getOne()
    {
        return one;
    }
    public Object getTwo()
    {
        return two;
    }
    Object one;
    Object two;
}




// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package genericity.demo;
import java.io.PrintStream;
// Referenced classes of package genericity.demo:
//            Pair

public class Test
{
    public Test()
    {
    }
    public static void main(String args[])
    {
        Pair pair = new Pair(Integer.valueOf(1), Integer.valueOf(2));
        int i = ((Integer)pair.getOne()).intValue();
        int j = ((Integer)pair.getTwo()).intValue();
        System.out.println((new StringBuilder()).append("one:").append(i).append(",two:").append(j).toString());
        Pair pair1 = new Pair(Character.valueOf('\u4E00'), Character.valueOf('\u4E8C'));
        char c = ((Character)pair1.getOne()).charValue();
        char c1 = ((Character)pair1.getTwo()).charValue();
        System.out.println((new StringBuilder()).append("one:").append(c).append(",two:").append(c1).toString());
        Pair pair2 = new Pair("I", "II");
        String s = (String)pair2.getOne();
        String s1 = (String)pair2.getTwo();
        System.out.println((new StringBuilder()).append("one:").append(s).append(",two:").append(s1).toString());
    }
}

Through the above analysis:

We can see that, Java compiler java source files will be compiled into bytecode .class file, the virtual machine to load and run. For a generic class, java compiler converts to a conventional non-generic code. The erase type T, then replace Object, insert the necessary cast. When the actual implementation of the Java Virtual Machine, generics do not know a thing, just know that ordinary class and code.

So why should such a generic design?

Because Java generics are just after 5 support, such a design for compatibility, and a choice of last resort.

6. Use the benefits of generics

  • Code reuse : We have a code can support different classes of.
  • Reducing the coupling : the separation between the code and the logical data types, to achieve decoupling.
  • Better readability : We use a set time, defined as a list List<String>, are instinctively that a String type of list storage.
  • Higher security : an important goal and the programming language is to destroy the bug in the cradle, can be nipped in writing, do not stay at runtime. If we define a List<String>such a list. When we put other non-String types of data to the list inside our IDE (such as Eclipse) will prompt an error. Even if no IDE. Compile time, Java compiler will prompt, which is called type safety . This sets up a security guard for the program. Similarly, the use of generic also eliminates troublesome cast using normal objects. In contrast, the use of ordinary objects, compile time and not be prompted. If the passed parameters and the type of final casts is inconsistent. ClassCastException will be running, to use the generic does not.

Guess you like

Origin www.cnblogs.com/nm666/p/11324345.html