首页 > 其他分享 >7-自定义泛型

7-自定义泛型

时间:2024-08-19 17:48:12浏览次数:14  
标签:String 自定义 Object List 泛型 new public

自定义泛型结构

泛型类的定义和实例化

  • 泛型------>添加限制
/*
Demo01就是一个普通的类
Demo01<E>就是一个泛型类
<>里面就是一个参数类型,但是这个类型是什么呢?这个类型现在是不确定的,相当于一个占位
但是现在确定的是这个类型一定是一个引用数据类型
 */
public class Demo01<E> {
    //属性
    int age;
    String name;
    E sex;//E类型的sex-----<E>中类型确定,则E sex类型确定

    //方法
    public void a(E n){

    }
    public void b(E[] m){

    }
}

class Test{
    public static void main(String[] args) {
        //在实例化Demo01时--->才会决定E的类型
        //Demo01实例化
        //1.实例化的时候不指定泛型:默认泛型为Object类型
        Demo01 gt1 = new Demo01();//相当于<Object>
        gt1.a("abc");//调用a方法
        gt1.a(17);
        gt1.a(9.8);
        gt1.b(new String[]{"a","b","c"});//调用b方法,需要传入Object类型数组

        //2.实例化时指定泛型
        Demo01<String> gt2 = new Demo01<>();
        gt2.sex = "男"; //sex属性变成String类型
        gt2.a("abc");//只能传入String类型
        gt2.b(new String[]{"a","b","c"});
    }

继承情况

1.父类指定泛型

class SubDemo01 extends Demo01<Integer>{//SubDemo01继承Demo01--->其中父类指定了泛型

}
class Test{
    public static void main(String[] args) {

        //指定父类泛型,那么子类就不需要再指定泛型了,可以直接使用
        SubDemo01 sgt = new SubDemo01();
        sgt.a(19);//只能传Integer
    }
}

2.父类不指定泛型

  • 若父类不指定泛型,那么子类也会变成一个泛型类,那这个E的类型可以在创建子类对象的时候确定
class SubDemo01_2<E> extends Demo01<E>{
    //SubDemo01_2继承Demo01--->其中父类未指定泛型
}
class Test{
    public static void main(String[] args) {

        //创建子类对象确定泛型
        SubDemo01_2<String> s = new SubDemo01_2<>();
        s.a("abc");//只能传入String类型
    }

应用场合

  • ArrayList实现就是运用泛型类,看懂API
  • 泛型接口跟泛型类一样

细节

  • 泛型类可以定义多个参数类型
//可以是多个参数类型
public class Demo02<A,B,C> {
    A age;
    B name;
    C sex;

    public void a(A m,B n, C x){
        
    }
}
  • 泛型类的构造器的写法

public class Demo02<A,B,C> {

​ public Demo02<A,B,C>(){
​ //构造器中不许加泛型
​ }
}

  • 不同的泛型的引用类型不可以相互赋值

ArrayList list1 = null;
ArrayList list2 = null;
list1 = list2;

  • 泛型如果不指定,那么就会被擦除,泛型对应的类型为Object类型
  • 泛型类中的静态方法不能使用类的泛型:

public static int c(A a){
//静态方法是在类加载时存在--->优先于对象存在,但是创建对象时A的类型才被确定,故不能用静态方法
return 10;
}

  • 不能直接使用E[]的创建:

public void a(A m,B n, C x){
A[] = new A[10];
}

泛型方法

  1. 什么是泛型方法
    • 这个方法的泛型的参数类型要和当前的类的泛型无关
public class Demo03<E> {
    public void a(E e){
        //这个不是泛型方法
    }
    public <T> void b(T t){
        //参数类型T 跟泛型类中的E 不同--->泛型方法
    }
}
  1. 泛型方法定义的时候,前面要加上

    • 原因:如果不加的话,会把T当作一种数据类型,然而代码中没有T类型那么就会报错
  2. 调用方法

    • T的类型是在调用方法的时候确定的
    public static void main(String[] args) {
        Demo03<String> tg = new Demo03<>();
        tg.b("abc");//T的类型在调用方法时才最终确定,故可以传任意类型
        tg.b(19);
        tg.b(true);
    }
  1. 泛型方法可否是静态方法
    • 可以是静态方法(静态方法优先于对象加载,没有对象是时静态方法随着类一起加载)
    • T的确定是随着方法的调用而确定,故可以是静态
public class Demo03<E> {
    public /*static*/ void a(E e){
        //这个不是泛型方法
        //不能是静态方法,E是随着对象确定才确定
    }
    public static <T> void b(T t){
        //参数类型T 跟泛型类中的E 不同--->泛型方法
        //T的类型是在调用方法时确定--->可以是静态
    }
}

泛型参数存在继承关系情况

    public static void main(String[] args) {
        Object obj = new Object();
        String s = new String();
        //String与Object有继承关系。(所有的类都直接或间接继承Object)
        obj = s ;//父类引用指向子类对象(多态一种形式)

        //两个数组之间存在数组关系吗
        Object[] objArr = new Object[10];
        String[] strArr = new String[10];
        objArr = strArr;//也可以,多态一种形式

        //对应泛型之间存在继承关系
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        list1 = list2;//报错,不存在父类子类关系
        //为什么?
        //ArrayList--->集合里都是Object类型
        /*list2中指定泛型String只是一个标签,
        本质集合都是Object类型的,
        限制只能String类型数据存入,
        实质也是将String类型数据放父Object类型的集合中
        故list1与list2底层本质是一样的(Object类型数组)
        list2指定String泛型只是在编译器,即写代码时进行限制
        所有list1与list2没有继承关系,
        是并列关系
         */
    }

通配符

1.在没有通配符的时候:

  • 下面的a方法,相当于方法的重复定义,报错
/*    public void a(List<Object> list){
    }
    public void a(List<String> list) {//想传String类型--->重载
    }
    public void a(List<Integer> list) {//想传Integer类型--->重载
    }
    报错
    泛型是对编译时进行的限制--->标签作
    故这几个重载参数本质都是Object-->重复定义
    --->通配符解决
    */

2.引入通配符:

        //这些泛型接口都是并列关系,没有继承关系
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<Integer> list3 = new ArrayList<>();

        //通配符:?
        List<?> list = null;
        list = list1;
        list = list2;
        list = list3;

3.使用通配符后改1中的a方法:

public class Demo05 {
/*    public void a(List<Object> list){
    }
    public void a(List<String> list) {//想传String类型--->重载
    }
    public void a(List<Integer> list) {//想传Integer类型--->重载
    }
    报错
    泛型是对编译时进行的限制--->标签作
    故这几个重载参数本质都是Object-->重复定义
    --->通配符解决
    */
    public void a(List<?> list){
        //内部遍历的时候永Object即可,不用?
        for (Object a : list) {
            System.out.println(a);
        }
    }

}
class Test3{
    public static void main(String[] args) {
        Demo05 demo05 = new Demo05();
        //其任何子类都可以传进去
        demo05.a(new ArrayList<Integer>());
        demo05.a(new ArrayList<String>());
        demo05.a(new ArrayList<Object>());//Object也属于?的子类
    }
}
  • 查看API中应用位置

通配符使用细节

  1. 通配符泛型,在内部操作时,用Object接收,而不用?
  2. 集合的写入操作
  3. 集合的读取操作
        //1.遍历:内部遍历的时候用Object即可,不用?
        for (Object a : list) {
            System.out.println(a);
        }

        //2.数据的写入操作:
        //传入list肯定是接到一个具体的集合
        //list.add("abc");--->出错,不能随意添加数据,因为在main函数传入数据指定了泛型
        list.add(null);//只能填null,但是也没有实际意义

        //3.数据的读取操作:
        Object s = list.get(0);//读取可以用Object类型接收

泛型受限

public class Person {//Person继承与Object
}
public class Student extends Person{
}
        //a,b,c集合中只是泛型存在子类父类关系,但这几个集合直接不存在子类父类关系(并列)
        List<Object> a = new ArrayList<>();
        List<Person> b = new ArrayList<>();
        List<Student> c = new ArrayList<>();
        /*
        1.开始使用泛型受限:泛型的上限
        List<? extends Person>:
        就相当于:
        List<? extends Person>是List<Person>的父类,是List<Person的子类>的父类
        (另注:之前的单独通配符List<?>实际上是List<? extends Object>)
         */
        List<? extends Person> list1 = null;
        //list1 = a;--->报错  a是Object类型,是Person的父类,超过泛型上限
        list1 = b;
        list1 = c;

        /*
        2.开始使用泛型受限:泛型的下限
        List<? super Person>:
        就相当于:
        List<? super Person>是List<Person>的父类。是List<Person的父类>的父类
         */
        List<? super Person> list2 = null;
        list2 = a;
        list2 = b;
        //list2 = c;--->报错   c是Student类型,是Person子类,超过泛型下限

标签:String,自定义,Object,List,泛型,new,public
From: https://www.cnblogs.com/Mc9r4dy/p/18367815

相关文章

  • gin 自定义validate错误消息
    以json的形式返回error,同时支持自定义错误消息msg。funcGetError(errerror,rinterface{})map[string]interface{}{ errs:=err.(validator.ValidationErrors) s:=reflect.TypeOf(r) for_,fieldError:=rangeerrs{ filed,_:=s.FieldByName(fieldError.Fi......
  • Visual Studio 2013 自定义动态库dll文件lib存放路径
    前言全局说明VisualStudio2013自定义lib存放路径一、说明环境:Windows7旗舰版VisualStudio2013二、设置说明在一个功能比较全的项目中,有可能会引入第三方库来完成某些功能,为了让目录结构、文件,清晰,会将引入的dll文件,放置到一个独立目录里。这样方便管理,也便......
  • Vue自定义轮播图
    目录前言代码效果演示详细代码实现思路轮播图实现代码组件使用代码前言    汇总一个最近写出来的效果,最新的设计稿里面要求实现一个轮播图,原本使用的Element-UI提供的轮播图不是很适配,所以选择自定义一个使用。文中附带代码实际效果演示视频。 ......
  • sonarqube添加一条自定义规则,扫描文件中出现的username和password,方法二,使用implement
    特别指出: 所以,sonarqube默认过滤掉了resources下的文件;以下代码可以扫出yml/xml/properties等文件中的敏感字符,当然是放在src/main下的,不是resources;下载源码与使用详情参考:Sonarqube自定义规则,部署SonarSource/sonar-java源码中示例规则:docs/java-custom-rules-exam......
  • C#泛型
    泛型(Generics)是C#中的一个重要特性,它允许您编写灵活、类型安全且可重用的代码。下面我将详细介绍泛型的概念、使用方法及其在C#中的实现细节。泛型的基本概念1.什么是泛型?泛型是一种允许您定义类型参数的机制,这些类型参数可以在编译时由具体的类型替换。这样,您可以编写一个通......
  • 书生大模型实战营3期 - 进阶岛 - 2 - Lagent 自定义你的 Agent 智能体
    文章目录闯关任务完成结果闯关任务任务描述:Lagent自定义你的Agent智能体任务文档:Lagent自定义你的Agent智能体完成结果使用Lagent自定义一个智能体,并使用LagentWebDemo成功部署与调用,记录复现过程并截图。环境准备/安装:#创建环境condacreate-n......
  • sonarqube添加一条自定义规则,扫描文件中出现的username和password,方法一
    下载源码与使用详情参考:Sonarqube自定义规则,部署SonarSource/sonar-java源码中示例规则:docs/java-custom-rules-example-yxchun-博客园(cnblogs.com)假设你已经有了sonarqube-java源码,并且已经把sonarqube部署到电脑上1、在check里面创建文件 MyTxtBlockCheck.javap......
  • SonarQube使用新增的自定义规则,进行maven项目扫描
    1、将新加规则添加到QualityProfiles中 2、创建, 写完名称回车  3、暂时将原先的规则禁用掉  点击apply; 499条规则被更改 4、添加我们新增的自定义规则  应用  规则已经添加;将我们创建的规则设置为默认扫描规则 5、进行项目扫描1)创建......
  • Sonarqube 自定义规则,部署SonarSource / sonar-java源码中示例规则:docs/java-custom-r
    自定义规则,可以参考sonar-java/docs/CUSTOM_RULES_101.mdat8.0.0.36314·SonarSource/sonar-java·GitHub1、下载一份sonarqube源码,配置好本地的环境,JDK17和mavendocs/java-custom-rules-example示例项目中会有写好的规则;我们可以先尝试将这些写好的规则添加到Sonarqube......
  • 【TCP/IP】自定义应用层协议,常见端口号
    互联网中,主流的是TCP/IP五层协议5G/4G上网,是有自己的协议栈,要比TCP/IP更复杂(能够把TCP/IP的一部分内容给包含进去了)应用层可以代表我们所编写的应用程序,只要应用程序里面用到了网络通信,就可以认为这个代码就是属于应用层的代码日常开发中最常用到的一层:使用大佬......