zoukankan      html  css  js  c++  java
  • 【Java基础】- 泛型

    1.什么是泛型

    JAVA 1.5的重大改变就是泛型的引入,实现了参数化类型的概念,使代码适用于多种类型,是通过解耦类、方法与所使用类型之间的约束。
    使得类型范围在接口的实现和类的集成之上。

    2.泛型类

    泛型类就是将泛型定义在类上,使用类时才会确定类型,类中的属性、方法也可以使用泛型

    2.1泛型类的定义

    public class GenericityClass<T> {
        //属性和方法可以直接使用泛型
        private T data;
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }
    
    注意:类上声明泛型只对非静态成员、非静态方法有效 泛型类中的静态方法不能直接使用类的泛型,可以声明为静态泛型方法再使用
        //编译报错
        public static void getT(T t){
        }
    
        //编译正常
        public static <T>  void getT(T t){
        }
        
    
    泛型的类型未确定时,只能调对象与类型无关的方法,不能调用对象与类型有关的方法。 例如集合的add()方法
        public static void main(String[] args) {
            List<? extends Number> testList = new ArrayList<>();
            testList.get(0);
            testList.add(1);//error
        }
    

    2.2泛型的使用

    使用时声明类型,类中的方法、属性都会为该类型。

    public static void main(String[] args) {
        GenericityClass<Integer> genericityClass = new GenericityClass<>();
        genericityClass.setData(10);
        System.out.println(genericityClass.getData());
    }
    

    3.泛型方法

    有时不需要将整个类定义为泛型,只需要将方法定义为泛型即可。

    3.1 泛型方法的定义

    public class GenericityFunc {
    
        public <T> void print(T t){
            System.out.println(t.toString());
        }
    }
    

    3.2 泛型方法的使用

    public static void main(String[] args) {     
        GenericityFunc genericityFunc = new GenericityFunc();
        genericityFunc.print("hello genericity function ");
        genericityFunc.print(10);
        genericityFunc.print(new int[]{1,2,3,4,5,6});
    }
    

    4.泛型的继承

    只要是Java类就可以存在继承关系,泛型的继承可以

    • 1.明确泛型类
    • 2.不明确泛型类
    //泛型父类
    public abstract  class FooClass<T> {
       public abstract T getT();
    }
    
    //子类不明确类型
    public class SonClass<T>  extends FooClass<T>{
    
        private T t;
    
        @Override
        public T getT() {
            return t;
        }
    }
    
    //子类指定类型
    public class SonClass2 extends FooClass<String>{
    
        private String data = "this is SonClass2";
    
        @Override
        public String getT() {
            return data;
        }
    }
    

    5.类型通配符

    T,E,K,V,?的区别
    本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替T,在可读性上可能会弱一些。通常情况下,T,E,K,V,?是这样约定的:

    • ?表示不确定的 java 类型
    • T (type) 表示具体的一个java类型
    • K V (key value) 分别代表java键值中的Key Value
    • E (element) 代表Element

    通配符 "?",通常是在变量赋值或变量声明时用的,?通配符来表示任意类型。
    用在声明泛型类或泛型方法会报错 即不能用于定义泛型

    List<?> unknownList;
    List<? extends Number> unknownNumberList;   //上界
    List<? super Integer> unknownBaseLineIntgerList; //下界
    

    当使用通配符作为形参时,只有变量明确定义了类型且不符合方法的声明才会编译异常

        public static void main(String[] args) {
            List commonList = new ArrayList();
            List<? extends Integer> integerList = new ArrayList<>();
            List<String> stringsList = new ArrayList();
            print(commonList); //编译通过
            print(integerList);//编译通过
            print(stringsList);//编译错误
    
    
        }
        public static  void print(List<? extends Number> list){
            for(int i=0;i<list.size();i++){
                System.out.println(list.get(i));
            }
        }
    

    6.泛型的擦除

    泛型是 Java 1.5 版本才引进的概念,在这之前是没有泛型的概念的,但显然,泛型代码能够很好地和之前版本的代码很好地兼容。因为,泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。

    在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,如<T>则会被转译成普通的 Object 类型,如果指定了上限如 则类型参数就被替换成类型上限String

    不能创建泛型数组的原因:数组中存储的类型是确定的,泛型在运行时,被擦除

    7.泛型的应用

    1.通用Service使用泛型类,实际实现时类指定业务pojo.

    public interface BasicService<T extends BaseEntity,M extends BaseMapper<T>> {
    
        T getModelById(Long id);
    
        List<T> getListByEqualsMap(Map<String,Object> mapEquals);
    
        T getModelByEqualsMap(Map<String,Object> mapEquals);
    
        List<T> selectBySelective(T t);
    
        int insertModel(T t,String userName);
    
        int insertSelective(T t,String userName);
    
        int updateById(T t,Long id,String userName);
    }
    
  • 相关阅读:
    Linux 用户管理命令-usermod和chage
    用户管理命令-passwd
    Linux 用户管理命令-useradd
    用户和用户组管理-用户管理相关文件
    用户和用户组管理-组信息文件
    用户和用户组管理-影子文件shadow
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/shinyrou/p/13525015.html
Copyright © 2011-2022 走看看