zoukankan      html  css  js  c++  java
  • 泛型

    1、泛型方法

    调用方法时需要指定泛型的具体类型。

    定义泛型方法的规则:

    • 所有的泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前。
    • 每一个类型参数声明部分包含一个或者多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
    • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
    • 泛型方法体的声明和其他方法一样。
    • 泛型的类型参数只能代表引用类型,不能是基本类型
    public <T> void test(){
    
    }
    public <T> String test1(){ return null; }
    public <T> T test2(){ return null; } public <T> T test3(T[] t){ return t[0]; } public <T> void test4(T t){ } public <T> T test5(T t){ return t; } public <T,E> void test6(T t, E e){ } public <T,E> T test7(){ return null; } public <T,E> T test8(T t, E e){ return t; } public <T,E,K> T test9(Map<T,E> map){ return null; }

    有界参数类型:

    有界是指对泛型的参数类型进行限制。

    有界类型参数使用extends关键字后面跟边界类型。注意:虽然用的是extends关键字,却不仅限于继承父类E的子类,也可以代指显现了接口E的子类。

    多边界泛型:<T extends A & B & C>。注意:A为父类,B、C是接口。

    public <T extends Number> void test10(T t){
        byte b = t.byteValue();
    }
    
    public <T extends Number& Comparable<T>> Integer test11(T t1,T t2,T t3){
        T max = t1;
        if(t2.compareTo(t1) > 0) {
            max = t2;
        }
    
        if(t3.compareTo(t1) > 0){
            max = t3;
        }
        return max.intValue();
    }

     调用泛型方法

    public void testGen(){
        //int[] abc = new int[2];      //参数类型只能是引用类型,不能是基本类型
        Integer[] abc = new Integer[2];
        Integer var1 = test3(abc);
    
        Integer var2 = test11(1,2,3);
    }

    泛型静态方法

    Java中任何方法,包括静态的和非静态的,均可以用泛型来定义,而且和所在类是否是泛型没有关系。注意,泛型类不允许在静态环境中使用。

    下面是泛型方法的定义:[public] [static] <T> 返回值类型 方法名(T 参数列表)

    public static <T> T getT(){
        return null;
    }

    2、泛型类

     泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。

    和泛型方法一样,泛型类的类型参数声明部分也包含一个或者多个类型参数,参数间用逗号隔开。

    一个泛型参数,也被称为一个类型变量,是用于指定一个泛型名称的标识符。

    public class TestGenerics<T> {
    
        private T t;
    
        private T a;
        private T b;
    
        public TestGenerics(T a,T b){
            this.a = a;
            this.b = b;
        }
    
        public void add(T t){
            this.t = t;
        }
    
        public T getA(){
            return a;
        }
    
        public T getB(){
            return b;
        }
    
        public static void main(String[] args) {
            TestGenerics<String> testGenerics = new TestGenerics<>("hello","world");
            String strA = testGenerics.getA();
            String strB = testGenerics.getB();
    
            TestGenerics<Integer> testGenerics1 = new TestGenerics<>(1,2);
            Integer intA = testGenerics1.getA();
            Integer intB = testGenerics1.getB();
        }
    
    }

    通配符

    通配符【?】表示一种未知的类型,常用在方法上。

    泛型【T】和通配符【?】的区别:

    • 泛型需要在方法返回值前面声明类型参数,通配符不需要
    • Java编译器将泛型推断成具体的类型,把通配符推断成未知类型。java编译器只能操作具体的类型,不能操作未知的类型。
    • 需要操作参数类型使用泛型,查看参数可以使用通配符

    无界通配:指的是不限制通配符的界限

    上界通配:定义通配符的上界,用关键字extends声明,形如 List<? extends Number>来定义,表示类型只能结束Number类型及其子类

    下界通配:定义通配符的下届,用关键字super声明,形如 List<? super Number>来定义,表示类型只能接受Number及其三层父类类型

    import java.util.ArrayList;
    import java.util.List;
    
    public class TestGenerics2{
    
        public static void main(String[] args) {
    
            List<Integer> list1 = new ArrayList<>();
            list1.add(1);
    
            List<String> list2 = new ArrayList<>();
            list2.add("hello");
    
            List<Number> list3 = new ArrayList<>();
            list3.add(2);
    
            getData(list1);
            getData(list2);
    
            getNum(list1);
           // getNum(list2); //只能是Number类型的及其一下类型
    
          //  getNum2(list1);  //只能是Number类型及其以上类型
            getNum2(list3);
        }
    
    
        /**
         * 泛型方法
         * @param list
         * @param <T>
         */
        public static <T> void setData(List<T> list){
            list.add((T) new Object());
            list.add(null);
        }
    
    
        /**
         * 无界通配符
         * @param list
         */
        public static void getData(List<?> list){
            System.out.println(list.get(0));
          //  list.add(new Object());   //无法添加
            list.add(null);
        }
    
        /**
         * 上界通配符
         * @param list
         */
        public static void getNum(List<? extends Number> list){
            System.out.println(list.get(0));
        }
    
        /**
         * 下届通配符
         * @param list
         */
        public static void getNum2(List<? super Number> list){
            System.out.println(list.get(0));
        }
    
    }

    3、泛型接口

    泛型接口的声明和非泛型接口的声明类似,除了在接口名后面添加了类型参数声明部分。

    通过类去实现泛型接口时,需要指定泛型参数T的类型

    public interface IGenerics3<T> {
        int f = 10;  //默认是 static final
    
        T next(T t); //默认是 public
    }

    实现类

    public class Generics3Impl implements IGenerics3<Integer>{
    
        @Override
        public Integer next(Integer integer) {
            return null;
        }
    }
    
    
    public class Generics3Impl implements IGenerics3<String>{
    
        @Override
        public String next(String s) {
            return null;
        }
    }
  • 相关阅读:
    ip报文
    常见端口
    navicat15 破解版
    谷歌跨域设置
    CSS flex弹性布局来做 页面底部自适应:页面高度不足时,在底部显示;页面高度超出时,随页面滚动(亲测有效)
    phpstorm 2019 激活码
    aes cbc模式
    Vue的安装及使用快速入门
    从SVN服务器端彻底删除错误提交版本
    Nginx配置https和wss
  • 原文地址:https://www.cnblogs.com/chenia/p/13891056.html
Copyright © 2011-2022 走看看