You read an article with java generics, the most comprehensive generic teaching the history of it.

Carefully reading this, ensure that you have a new understanding of the generic, if not, please follow the network cable to beat me.

Outline

Reference answer under Baidu Encyclopedia

Generics are programming language one property. Allows the programmer to define the variable portion of the time writing code in a strongly typed programming language, those parts must be made before the specified use. A variety of programming languages and their compilers , operating environment are not the same support for generics. The parameters of the type to achieve a data type code reuse improve software development productivity. Generic classes are reference types, heap objects, mainly the introduction of the concept of type parameters.

My understanding is: generic type is to clear defer to create a special type of object or when calling methods before going to clear.

Parameterized type, the type is passed as a parameter the same as, Object <data type> is a reference type and there can not be a basic type.

such as:

Object<Integer>  //true
Object<int> //false
复制代码

Why is there a generic data types can not be the basic type it?

At compile time because the virtual machine will strip into a generic type of Object, but not basic types Object types, generic data types which are not basic types.

Why use generics it?

Java language advantages of the introduction of generics is safe and simple. The benefits of generics are checked at compile time type safety, and all the cast are automatic and implicit, improve code reuse.

It is important is to eliminate the mandatory conversion, reducing the opportunities for error, for example:

public class Test {
    public static void main(String[] args){
        List list = new ArrayList();
        list.add("1"); 
        list.add(1);
        int i = (int)list.get(0); // java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
        int j = (int)list.get(1);
    }
}
复制代码

In the above code compile time is no problem, because the add method list is of type Object, so there is no problem at compile time, but run-call list when we do not know when specific list kept inside what types of arguments, so take when it is possible to convert the type of error will be reported.

If a generic error above would not have happened.

public class Test {
    public static void main(String[] args){
        List<String> list = new ArrayList();
        list.add("1");
        list.add(1);//在编译期就会出错,因为用了泛型,虚拟机就会在编译期的时候检查泛型类型安全。
    }
}
复制代码

Generic exists only in compile time.

for example.

public class Test {
    public static void main(String[] args) throws Exception{
        List<String> list = new ArrayList();
        list.add("hello");
        //list.add(23) //编译期会报错
        Class c = Class.forName("java.util.ArrayList");
        Method m = c.getMethod("add",Object.class);
        m.invoke(list,23);
        System.out.println(list); // [hello, 23]
    }
}
复制代码

By the above shows, generics at compile only effective, why run it fails, it is because generics erased concept, popular point, is the generic information will not be operational phase.

The use of generics

There are three practical ways Generics

Generic class: public class Test<T>}{}T represents unknown type

Generic Interface: public interface Test<T>{}and as defined class

Generic method:public <T> void Test(T name){}

Use generic class

Generic class has a very important role in java, where we use the most is ArrayList, HashMap, HashSet.

Since it takes you to read Java generics, certainly not the source of those containers inside Yeah, those containers have been perfect if you want to take you a look at it, certainly ever more dizzy, so we own definition of a generic class out.

//这个T可以换成随便一个字母 ,只不过我写泛型都用的T,你可以换成A,B,C...
public class Test<T> {
    T name;
    public Test(T name){
        this.name = name;
    }
    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }

复制代码
//如果不传泛型类型的话,那么默认的就是Object型什么都可以传
Test test = new Test("hello");
//传入的数据类型不为基本类型,否则编译期会报错,开头我解释过为什么会报错了
Test<Integer> test1 = new Test<>(418);
复制代码

Use generic interface

Definition of generic interface and generic class of similar, our common generic interface is, List, Map, Set.

First of all the old rules of our own definition of a generic interface.

public interface Test<T>{
    T getName(T name);
}
复制代码
//如果实现接口的时候不传入数据类型的话,需要将泛型声明也要写到类中要不然会报错
class Test1<T> implements Test<T>{

    @Override
    public T getName(T name) {
        return null;
    }
}

//实现接口的时候传入数据类型的话,就不用把泛型声明也写到类中了
class Test2 implements  Test<String>{

    @Override
    public String getName(String name) {
        return name;
    }
}
复制代码

Using generic methods

Using generic methods

public <T> void getName(T name){} 
public <T,K> void getNameAndValue(T name, K value){}
public <T,K,V> void getNameAndValueAndV(T name, K value, V v){}//总的来说就是参数需要多少泛型,返回值前面就得定义几个泛型要不然编译期会出错
复制代码

Generic wildcards

Why use wildcards it?

is the inheritance relationship between classes and java inside, such as Cat extends Animals, then the Cat is the Animal subclasses, but collections are not inherited this concept, for example, List<Cat> catListand List<Animals> animalListyou can not say animalList is catList parent, it is difficult to see Contact between the two classes out of, but we just want to make list that includes only the sub-category Animals of how to do it?

  1. One is the number of list Animals number of sub-class definition, although this method can also be achieved, however Animals if one hundred, one thousand, ten thousand sub-class of this method is that you do not do it too time consuming .

  2. The second is to use wildcards to achieve. For example: List<? extends Animals> animalsthis time the animals will only add subclasses of Animals, and get a list.

The basic concept of a wildcard?

  1. Borderless wildcard:? For example, you can receive all types of generic unknown

    public class Test {
       public static void main(String []args){
           List<Integer> list = new ArrayList<>();
           list.add(1);
           list.add(2);
           list.add(3);
           list.add(4);
           List<String> stringList = new ArrayList<>();
           stringList.add("h");
           stringList.add("e");
           stringList.add("l");
           stringList.add("l");
           stringList.add("o");
           getList(stringList);
           getList(list);
       }
        //无论传入什么List都会被接收
       public static List getList(List<?> list){
           return list;
       }
    复制代码

    Use List <?> List method claim can not add, because you do not know what the type is, but list.add (null) on it, because there are all types of null. for example

    public static List getList(List<?> list){
        // list.add(1);//会报参数不匹配的错误,编译期报错
        // list.add("hello");//会报参数不匹配的错误,编译期报错
           list.add(null);//添加成功
           return list;
    }
    复制代码

    Object can only be used to receive a get method, because you do not know what your type yes.

    public static List getList(List<?> list){
        int i = list.get(0); //编译期报错
        String j = list.get(1); //编译期报错
        Object o = list.get(3); //运行正确
        return list;
    }
    复制代码
  2. The boundary wildcard: subtypes may receive generic E and E, there is not only the E class Oh, may be an interface, see example <extends E?>.

    //这个是继承了类的用法
    public class Test {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            getList(list);
            List<String> strings = new ArrayList<>();
            strings.add("hello");
            getList(strings);//编译期报错
        }
    
        public static List getList(List<? extends Number> list) {
            return list;
        }
    }
    
    
    复制代码
    public class Test {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            getList(list);// 编译期报错
            List<Test2> test2s = new ArrayList<>();
            getList(test2s);
        }
        //上边界为接口的实现,只要是实现了此接口的类都可以被当做泛型传进来
        public static List getList(List<? extends Test1> list) {
            return list;
        }
    }
    
    interface Test1{
    
    }
    class Test2 implements Test1{}
    复制代码

    Above can be seen on the boundary <? Extends E> is that you have to be passed in the type subclasses E, or a class that implements the interface.

  3. Lower boundary wildcard: <? Super E> is passed have to be the type of parent class E and E's, for example

    public class Test {
        public static void main(String[] args) {
            List<Animals> animals = new ArrayList<>();
            getList(animals); 
            List<Cat> cats = new ArrayList<>();
            getList(cats);
            List<Dog> dogs = new ArrayList<>();
            getList(dogs);//编译出错,因为Dog不是Cat的父类
    
        }
    
        public static List getList(List<? super Cat> list) {
            return list;
        }
    }
    class Animals{}
    class Cat extends  Animals{}
    class Dog extends  Animals{}
    复制代码

The End

I think in java which we use the most is the generic List, Map both the bar, in fact, our own programming when multi-purpose use of generics can reduce a certain amount of code, but also make the code look better, with Lei Jun's words, others say I write code like poetry, I hope you will go far more in the way of java ah.

Finally, like this article, then trouble your little hand like a point of a point and then go forward, each forwarding your thumbs are my writing power.

Watch one thousand Jue (jue) public number, give me back a message exchanges with it.

Guess you like

Origin juejin.im/post/5dfde5dc51882512327a64b2