泛型

作者: ttyttytty | 来源:发表于2020-01-08 00:30 被阅读0次

what

方法在实现的时候,不指定入参/返回值的具体类型,等调用的时候再确定。

类定义,部分成员/方法也可以,等实例化的时候再确定。

核心概念:参数化类型,把类型当作是参数传递。

why

不用指定类型,更通用,不用强制类型转换。

where

使用场景:集合类,不定类型,通用性方法。

how

1.泛型方法

```

public class GenericMethod {

public static void main(String[] args) {

}

//    private List convert2Father() {

//        List list = new ArrayList<>();

//        list.add(1);

//        list.add(2);

//        // extends 不set

//        return list;

//    }

//    private List convert2Son() {

    private Listconvert2Son() {

List list =new ArrayList<>();

        list.add(1);

        list.add(2);

        // super 可set

        return list;

    }

}

```

```

import java.util.ArrayList;

import java.util.List;

public class GenericRetuenTest {

public static void main(String[] args) {

List superList =getList(Super.class);

        System.out.println("superList.size():" + superList.size());

        for (Super element : superList) {

System.out.println(element);

        }

System.out.println("!!!!!!");

        List subAList =getList(SubA.class);

        System.out.println("subAList.size():" + subAList.size());

        for (SubA element : subAList) {

System.out.println(element);

        }

System.out.println("!!!!!!");

        List subBList =getList(SubB.class);

        System.out.println("subBList.size():" + subBList.size());

        for (SubB element : subBList) {

System.out.println(element);

        }

System.out.println("!!!!!!");

        List stringList =getList(String.class);

        System.out.println("stringList.size():" + stringList.size());

        for (String element : stringList) {

System.out.println(element);

        }

}

private static ListgetList(Class clazz) {

List result =new ArrayList();

        Super[] array = {new Super(), new SubA(), new SubB()};

        for (Super element : array) {

if (clazz.isAssignableFrom(element.getClass())) {

result.add(clazz.cast(element));

            }

}

return result;

    }

private static class Super {

@Override

        public StringtoString() {

return "Super";

        }

}

private static class SubAextends Super {

@Override

        public StringtoString() {

return "SubA";

        }

}

private static class SubBextends Super {

@Override

        public StringtoString() {

return "SubB";

        }

}

}

```

2.泛型类

```

public class GenericClassFather {

private T t;

    // public static T t;//静态成员,不可泛型

    public void setObj(T t) {

this.t = t;

    }

public T getObj() {

return this.t;

    }

public void show(T t) {

System.out.println(t.toString());

    }

}

```

```

public class GenericClassSonStringextends GenericClassFather {

@Override

    public void show(T t) {

System.out.println("ObjectToolString:"+t.toString());

    }

}

public class GenericClassSonTextends GenericClassFather {

@Override

    public void show(T1 t1) {

System.out.println("T:"+t1.toString());

    }

}

```

```

import java.util.Date;

public class GenericClassTest {

public static void main(String[] args) {

GenericClassFather tool=new GenericClassFather<>();

        tool.setObj("generic");

        System.out.println(tool.getObj());

        tool.show("qq");

        GenericClassFather toolDate=new GenericClassFather<>();

        toolDate.setObj(new Date());

        System.out.println(toolDate.getObj());

        GenericClassSonString genericSonClassString =new GenericClassSonString();

        genericSonClassString.show("123");

        GenericClassSonT genericClassSonT =new GenericClassSonT();

        genericClassSonT.show("345");

    }

}

```

**类上声明的泛形只对非静态成员有效**

继承(子类指定类型or不指定)

3.通配符

泛型中的<Object>并不是像以前那样有继承关系的,也就是说List<Object>和List<String>是毫无关系的!!!

不能依靠object类来实现继承,如,List<Object>

3.1 ?号通配符表示可以匹配任意类型,不能set/add,不知道盘子的兜底

3.2List<? extends Number>上界通配符,不能set(子类盖父类内存,盖不住)

3.3<? super >下界通配符,可以set

```

package Generics;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.LinkedList;

import java.util.List;

public class SuperExtends {

public static void main(String[] args) {

List superList =getList(Super.class);

        System.out.println("superList.size():" + superList.size());

        for (Super element : superList) {

System.out.println(element);

        }

System.out.println("*****************************************");

        List subAList =getList(SubA.class);

        System.out.println("subAList.size():" + subAList.size());

        for (SubA element : subAList) {

System.out.println(element);

        }

System.out.println("*****************************************");

        List subBList =getList(SubB.class);

        System.out.println("subBList.size():" + subBList.size());

        for (SubB element : subBList) {

System.out.println(element);

        }

System.out.println("*****************************************");

        List stringList =getList(String.class);

        System.out.println("stringList.size():" + stringList.size());

        for (String element : stringList) {

System.out.println(element);

        }

}

//    private static void GenericTest2() {

//        //https://blog.csdn.net/w372426096/article/details/78081552

        //如果List<S>复合类型是协变的,那么如果S是T的子类,则List<S>也是List<T>的子类。如果List<S>是逆变的,结果颠倒,List<T>会变成List<S>的子类。

        //Java中数组是协变的

        //Java中泛型是不变的

        //<? extends>实现了泛型的协变:List list = new ArrayList();

        //<? super>实现了泛型的逆变 :List list = new ArrayList();

        //传参要求是协变,返回值要求是逆变的

//

//        //直接赋值,泛型不协变

//        //父类集合添加子类集合是可以的

//        ArrayList arrayList1 = new ArrayList();

//        arrayList1.add("123");

//        ArrayList<Object> arrayList2 = arrayList1;//直接赋值,泛型不协变

//        arrayList1 = new ArrayList<Object>();// 直接赋值,泛型不协变

//        ArrayList arrayList2 = new ArrayList<>();

//        arrayList2.add(arrayList2.get(0));

//        arrayList2.addAll(arrayList1);//父类集合添加子类集合是可以的

//

//        //父类=list.get():拿出来往上塞,相当于放到左值(get出来放到父类里,super的话只能放到object里),向上类型转换Object obj = fathers1.get(0);

//        //list.set(子类)=list.get(i)=子类:往下放进去,相当于塞右值进去(set进去的只能是子类,extends的话编译器能确定的子类只能是null),向下类型转换  fathers1.add( Son1 )  =》father = son

//        //extends 做左值字面意思可协变

//        //get:extends的类的左值/向上类型转换:父类

//        //set:extends的类的右值/向下类型转换:null

//        List fathers1 = new ArrayList<>();

//        List son1s = new ArrayList<>();

//        List grandpas1 = new ArrayList<>();

//

//        fathers1 = son1s; //extends的协变,左右值关系不满足,但是是定义  todo

//        grandpas1 = fathers1;//不满足extends的定义 Required type: List<Grandpa>  Provided:List<capture of ? extends Father> todo

//        fathers1.addAll(son1s);//找右值,null

//

//        fathers1.add(new Son1()); //找右值,null

//        fathers1.add(new Father());//找右值,null

//        fathers1.add(null);//找右值,null

//

//        Object obj = fathers1.get(0);//找左值,父类

//        Grandpa grandpa = fathers1.get(0);//找左值,父类

//        Father father = fathers1.get(0);//找左值,父类

//        Son1 son1 = fathers1.get(0);//子类左值父类,不可行赋值逻辑关系

//

//        //super 逆变

//        //get:super的左值/向上类型转换:object

//        //set:super的右值/向下类型转换:子类

//        List fathers2 = new ArrayList<>();

//        List grandpas2 = new ArrayList<>();

//        List son2s = new ArrayList<>();

//

//        fathers2 = grandpas2; //super的逆变,左右值关系满足

//        grandpas2 = fathers2;//左右值关系不满足

//        fathers2.addAll(son2s);

//

//        fathers2.add(new Son1());//找右值,子类

//        fathers2.add(new Father());//找右值,子类

//        fathers2.add(new Grandpa());//错误,找右值,子类  Father =Grandpa  不可行的赋值关系

//        fathers2.add(null);//找右值,子类

//

//        Object object = fathers2.get(0);//找左值,Object

//        Grandpa grandpaa = fathers2.get(0);//找左值 object  如果是父亲(Grandpa)=父亲的父亲(? super Father),就是错误的赋值逻辑

//    }

    private static void GenericTest() {

//泛型只在编译期间有效,运行时会擦除

        ArrayList a =new ArrayList();

        ArrayList b =new ArrayList();

        ArrayList c =new ArrayList();

        List aList =new ArrayList<>();

        List aLinkedList =new LinkedList<>();

        List asList = Arrays.asList();

        System.out.println(a.getClass());

        System.out.println(b.getClass());

        System.out.println(c.getClass());

        System.out.println(aList.getClass());

        System.out.println(aLinkedList.getClass());

        System.out.println(asList.getClass());

        a.add("hello");

        Class aClass = a.getClass();

        try {

Method aAdd = aClass.getMethod("add", Object.class);

            aAdd.invoke(a, 100);

            System.out.println(a);

        }catch (NoSuchMethodException e) {

e.printStackTrace();

        }catch (IllegalAccessException e) {

e.printStackTrace();

        }catch (InvocationTargetException e) {

e.printStackTrace();

        }

}

//    private static List getSubList(List data) {

//        List result=new ArrayList<>();

//        for (Son1 datum : data) {

//            result.add(datum);

//        }

//    }

    private static ListgetList(Class clazz) {

List result =new ArrayList();

        Super[] array = {new Super(), new SubA(), new SubB()};

        for (Super element : array) {

if (clazz.isAssignableFrom(element.getClass())) {

result.add(clazz.cast(element));

            }

}

return result;

    }

private static class Super {

@Override

        public StringtoString() {

return "Super";

        }

}

private static class SubAextends Super {

@Override

        public StringtoString() {

return "SubA";

        }

}

private static class SubBextends Super {

@Override

        public StringtoString() {

return "SubB";

        }

}

}

class Grandpa {

static {

System.out.println("爷爷在静态代码块");

    }

}

class Fatherextends Grandpa {

static {

System.out.println("爸爸在静态代码块");

    }

public static int factor =25;

    public Father() {

System.out.println("我是爸爸~");

    }

}

class Son1extends Father {

static {

System.out.println("儿子在静态代码块");

    }

public Son1() {

System.out.println("我是儿子~");

    }

}

```

3.4 通配符和泛型方法

大多时候,我们都可以使用泛型方法来代替通配符的…..

如果参数之间的类型有依赖关系,或者返回值是与参数之间有依赖关系的。那么就使用泛型方法

如果没有依赖关系的,就使用通配符,通配符会灵活一些.


#

泛型:

void onResponse(int err_code, T objData);数据T转为需要的类型,例如List?

泛型参考:SharedPreferencesJsonDAO,注意提前声明类型<T>,记得通配符super和extends,

分类别处理逻辑时,instanceof分支(UserInfoDao)

<? extends T >  所有的泛型类必须<=类T,父类上限是T,?是T的子类。  不能往里存(子类的内容/粒度大于父类,不知道存哪里啊),只能往外取

<? super T> 所有的泛型类必须>=类T,子类的下限是T,?是T的父类。    存正常(基类的粒度/内容都小于T,都可以存下),取必须赋给OBject(不知道父类super向上究竟的界在哪里,只能取最大父类Object)

PECS:producer extends consumer super:频繁存/set要有最大粒度的底盘兜住,所以用super;频繁取/get,用extends,可以取出来放到指定盘子里。

类型转换原则:(内容少的->内容多的,粒度小的->粒度大的,内存小空间->大空间),少的部分赋默认值/方法。

int->double,可以,知识其他的内存填默认值0;

double->int,不可以,内容/精度丢失。

基类=子类(基类指向子类,基类小内容内存覆盖子类多内容,缺失的部分赋默认值,调用子类的默认构造函数);

子类=父类(子类大内存扣在父类小内存上,丢失)。

https://blog.csdn.net/sjm19901003/article/details/44743801

### 动态比类型

- 因为在泛型代码内部,无法获取任何有关泛型参数类型的任何信息!,Java的泛型就是使用擦除来实现的

那如何获取参数类型?——**类型标签Class< T>**

```

class A{}

class Bextends A{}

public class TestInstance {

private Classt;

    public TestInstance(Class t){

this.t = t;

    }

public boolean compare(Object obj){

return t.isInstance(obj);

        // 相当于obj  instanceof t

    }

public static void main(String[] args) {

TestInstance ti =new TestInstance(A.class);

        System.out.println(ti.compare(new A()));

        System.out.println(ti.compare(new B()));

    }

}

```

相关文章

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

  • Web笔记-基础加强

    泛型高级应用 自定义泛型方法 自定义泛型类 泛型通配符? 泛型的上下限 泛型的定义者和泛型的使用者 泛型的定义者:...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

  • Kotlin泛型的高级特性(六)

    泛型的高级特性1、泛型实化2、泛型协变3、泛型逆变 泛型实化 在Java中(JDK1.5之后),泛型功能是通过泛型...

  • Java 19-5.1泛型

    泛型类定义泛型类可以规定传入对象 泛型类 和泛型方法 泛型接口 如果实现类也无法确定泛型 可以在继承类中确定泛型:

  • 【Swift】泛型常见使用

    1、Swift泛型4种 泛型函数泛型类型泛型协议泛型约束 2、泛型约束3种 继承约束:泛型类型 必须 是某个类的子...

网友评论

      本文标题:泛型

      本文链接:https://www.haomeiwen.com/subject/lyljactx.html