泛型类 订阅
什么是泛型,如何使用和定义泛型?泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和其方法的参数类型出现。泛型方法可以将其类型参数用作其返回值的类型或者其形参的类型之一。下面的代码阐释一个简单的泛型类定义。 展开全文
什么是泛型,如何使用和定义泛型?泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和其方法的参数类型出现。泛型方法可以将其类型参数用作其返回值的类型或者其形参的类型之一。下面的代码阐释一个简单的泛型类定义。
信息
性    质
Visual Basic代码
分    类
占位符的类、结构、接口和方法
含    义
泛型类定义
中文名
泛型类
泛型类代码
Public Class Generic(Of T)Public Field As TEnd ClassC# 代码public class Generic{public T Field;}C++ 代码generic public ref class Generic{public:T Field;};在创建泛型类的实例时,会指定实际类型来替换类型参数。这会建立一个新的泛型类,称为构造泛型类,选定的类型将替换所有出现的类型参数。最后得到按照您选择的类型定制的类型安全的类,如下面的代码所示。Visual Basic 代码Dim g As New Generic(Of String)g.Field = "A string"C# 代码Generic g = new Generic();g.Field = "A string";C++ 代码Generic^ g = gcnew Generic();g->Field = "A string";
收起全文
精华内容
下载资源
问答
  • 泛型:泛型类与泛型方法
    千次阅读
    2022-03-16 10:40:33

    泛型

    JDK1.5新特性

    优点:

    1. 类型安全:编译时检测类型
    2. 减少类型转换

    泛型类

    概念:在类声明体中用到了类型参数。

    语法:

    /*
    class 类型名<泛型标识,泛型标识, ...>{
        private 泛型标示 变量名;
    }
    */
    public class GenericDemo<T> {
        private T key;
    
        public GenericDemo(T key) {
            this.key = key;
        }
    
        public T getKey() {
            return key;
        }
    
        public void setKey(T key) {
            this.key = key;
        }
    
        public static void main(String[] args) {
            
            /*
            类名<具体的数据类型> 对象名 = new 类目<具体的数据类型>();
    
            JDK1.7后,可以省略成这样:
            类名<具体的数据类型> 对象名 = new 类目<>();
            */
            GenericDemo<Integer> integerGenericDemo = new GenericDemo<>(10);
            GenericDemo<String> stringGenericDemo = new GenericDemo<>("abc");
            //如果没有指定具体的数据类型,此时,操作类型是Object
            GenericDemo genericDemo = new GenericDemo("genericDemo");
    
            System.out.println(integerGenericDemo.key);
            System.out.println(stringGenericDemo.key);
            System.out.println(genericDemo.key);
            //泛型类型在逻辑上可以看成是多个不同的类型,但实际上是相同类型
          System.out.println(integerGenericDemo.getClass()==stringGenericDemo.getClass());	//输出结果为true
        }
    }
    
    
    

    注意:

    1. 泛型类只支持类类型不支持基本数据类型(如int),但可以用包装类(如Integer )

    泛型标识<>:类型形参

    由外部使用类的时候来指定

    泛型标识含义
    TType
    EElement
    KKey
    VValue

    泛型类的继承

    1. 子类也是泛型类,子类和父类的泛型标识要一致。子类也可以扩展泛型标识,但子类中至少有一个泛型标识与父类相同

    2. 子类不是泛型类,父类要明确泛型的数据类型

    //1.子类也是泛型类,子类和父类的泛型标识要一致
    
    class Child<T> extends Parent<T>{}
    
    //也可以扩展,但子类中至少有一个泛型标识与父类相同
    class Child<T,E> extends Parent<T>{}
    
    //2.子类不是泛型类,父类要明确泛型的数据类型
    
    class Child extends Parent<String>{}
    

    泛型接口

    1. 实现类不是泛型类时,接口要明确数据类型
    2. 实现类也是泛型类时,实现类和接口的泛型类型要一致

    泛型方法

    泛型方法比泛型类更加灵活

    泛型类和泛型方法的区别
    泛型类实例化类的时候指明泛型的具体类型
    泛型方法调用方法的时候指明泛型的具体类型

    语法

    修饰符 <T,E,...> 返回值类型 方法名(形参列表){
        方法体... 
    }
    
    1. public 和 返回类型中间的标识符,可以理解为,声明该方法为泛型方法
    2. 只有声明了的方法是泛型方法,泛型类中的成员方法不是泛型方法
    3. 表明,该方法使用泛型类型T,可以使用在返回类型,传入参数列表,方法体

    泛型方法与可变参数

    public class GenericDemo<T> {
    
        public static <E> void print(E... e){
            for(int i = 0; i < e.length; i++){
                System.out.println(e[i]);
            }
        }
    
        public static void main(String[] args) {
            GenericDemo.print(1,2,3,4,5);
            GenericDemo.print("a","b","c");
        }
    }
    

    类型通配符: ?

    概念:用“?”代替具体类型,是类型实参,不是类型形参

    /*
    	类型通配符上限
    	语法:
    	类/接口 <? extends 实参类型>
    	作用:要求该泛型的类型只能是《该实参类型或其子类型》  
    */
    
    public static void showAnimal(ArrayList<? extends Cat> list){
        for(int i;i<list.size();i++){
            Cat cat = list.get(i);
            System.out.println(cat);
        }
    }
    public static void main(String[] args){
        ArrayList<Animal> animals = new ArrayList<>();
        ArrayList<Cat> cats = new ArrayList<>();
        ArrayList<MiniCat> miniCats = new ArrayList<>();
        
        //showAnimal(animals); 编译报错
        showAnimal(cats);
        showAnimal(miniCats);
    }
    
    /*
    	类型通配符下限
    	语法:
    	类/接口 <? super 实参类型>
    	作用:要求该泛型的类型只能是《该实参类型或其父类型》  
    */
    

    类型擦除

    概念:

    JDK1.5以前没有泛型,但泛型代码能很好地和之前版本的代码兼容,是因为,泛型信息只存在于代码编译阶段,

    在进入JVM之前,与泛型相关的信息会被擦除

    更多相关内容
  • 下面小编就为大家带来一篇浅谈java中定义泛型类和定义泛型方法的写法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要为大家详细介绍了java泛型类定义与使用的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • C# 泛型类(函数)的实例化小例子,需要的朋友可以参考一下
  • 【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 ) https://hanshuliang.blog.csdn.net/article/details/114059611 博客源码快照
  • 泛型类、泛型方法、泛型接口、泛型委托 泛型类、泛型方法、泛型接口、泛型委托
  • 详解c# 泛型类的功能

    2020-12-16 21:37:08
    泛型类中,由于不知道泛型参数T是什么类型,可能是引用类型,也可能是值类型,因此不能将null等赋予泛型类型。如何对泛型对象赋初值、如何保证泛型的正确性等,以使用泛型文档管理器为例:  文档管理器用于从队列...
  • 闲来无事,自己研究了泛型类的简单的使用,where表示泛型约束,表示泛型类型中的参数只能是car类型,IEnumerable是一个接口,一个集合要支持FOREAch遍历,必须实现IEnumerable接口 代码如下:public class Car { ...
  • winform窗体继承泛型类时,设计器无法使用解决办法: 当我们使用winform程序时,winform窗体程序和控件程序都是可以通过设计器进行控件拖拽的,但如果我们继承了一个带有泛型的form基类.那么设计器是无法使用的. 这时...
  • 主要介绍了Java泛型类与泛型方法的定义,结合实例形式详细分析了java泛型类与泛型方法定义、用法及相关操作注意事项,需要的朋友可以参考下
  • 泛型类 泛型类封装不是特定于具体数据类型的操作。泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等。像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。 对于大多数...
  • 一、泛型类用法、 二、泛型方法用法、 三、泛型通配符 、 四、泛型安全检查、





    一、泛型类用法



    泛型类用法 : 使用时先声明泛型 , 如果不声明泛型 , 则表示该类的泛型是 Object 类型 ;


    泛型类代码 :

    public class Student<T> {
    
        private String name;
        private int age;
        /**
         * 该数据的类型未知
         *  使用泛型表示 , 运行时确定该类型
         */
        private T data;
    
        public Student(String name, int age, T data) {
            this.name = name;
            this.age = age;
            this.data = data;
        }
    }
    

    指明泛型类型 : 指定 泛型类 的泛型为 String 类型 , 那么在该类中凡是使用到 T 类型的位置 , 必须是 String 类型 , 泛型类的 泛型声明 , 使用时在 类名后面 声明 ;

            // 指定 泛型类 的泛型为 String 类型
            //      那么在该类中凡是使用到 T 类型的位置 , 必须是 String 类型
            //      泛型类的 泛型声明 , 使用时在 类名后面 声明
            Student<String> student = new Student("Tom", 16, "Cat");
            String data = student.getData();
    

    不指明泛型类型 : 如果不 指明泛型类型 , 则 泛型类型 默认为 Object 类型 ; 如下面的示例 , 获取的 泛型类型的变量也是 Object 类型 , 需要强转为 String 类型 ;

            // 如果不 指明泛型类型
            //      则 泛型类型 默认为 Object 类型
            Student student1 = new Student("Tom", 16, "Cat");
            // 获取的 泛型类型的变量也是 Object 类型 , 需要强转为 String
            String data1 = (String) student1.getData();
    




    二、泛型方法用法



    泛型方法 : 给下面的泛型方法 , 传入 String 作为参数 , 则 泛型方法中的 T 的类型就是 String 类型 ;

        public <T, A> T getData2(T arg){
            T data = arg;
            return data;
        }
    

    指定泛型的方法 : 指定 泛型方法 的泛型类 , 泛型方法 的泛型声明 , 在调用时 方法名的前面 声明 ; 这种用法很少见 ;

            // 指定 泛型方法 的泛型类
            //      泛型方法 的泛型声明 , 在调用时 方法名的前面 声明
            student.<String, Integer>getData2("Mouse");
    

    不指定泛型的方法 : 泛型方法 中 也可以不声明泛型类型 , 传入的参数是 泛型 T 类型 , 如果给传入参数设置 String , 隐含将泛型 T 设置为 String 类型 ;

            // 泛型方法 中 也可以不声明泛型类型
            //      传入的参数是 泛型 T 类型
            //      如果给传入参数设置 String , 隐含将泛型 T 设置为 String 类型
            String data2 = student.getData2("Mouse");
    




    三、泛型通配符 <?>



    如果现在的泛型类型不确定 , 则使用 ? 作为通配符 , 该用法与将泛型类型指定为 Object 类型用法相同 ;

    ? 通配符用法示例 :

            // 使用 <?> 通配符作为泛型
            //      默认将泛型指定为 Object 类型
            Student<?> student2 = new Student("Tom", 16, "Cat");
            String data2 = (String) student1.getData();
    

    上述 ? 通配符用法等效于下面的不指定泛型的用法 :

            // 如果不 指明泛型类型
            //      则 泛型类型 默认为 Object 类型
            Student student1 = new Student("Tom", 16, "Cat");
            // 获取的 泛型类型的变量也是 Object 类型 , 需要强转为 String
            String data1 = (String) student1.getData();
    




    四、泛型安全检查



    注意下面 2 2 2 种泛型的用法 , 推荐使用第一种方法 ;

            // 泛型的安全检查
            // 推荐写法
            Student<String> student3 = new Student<>("Tom", 16, "Cat");
            // 不推荐写法
            Student student4 = new Student<String>("Tom", 16, "Cat");
    

    使用 new 关键字创建对象 , 是发生在运行时 , 也就是 new Student<String>("Tom", 16, "Cat") 代码是在运行时才会执行 , 根本起不到 编译时 安全检查 的作用 , 从 安全检查 方面考虑 , 这种写法没有意义 ;


    以 List 泛型为例 :

    • 编译期进行安全检查示例 :
            // 编译器 在 编译期 进行检查
            List<String> list1 = new ArrayList<>();
            list1.add(1);
    

    会报如下错误 ;

    在这里插入图片描述

    • 编译期不进行安全检查示例 :
            // 编译器 在 编译期 不进行检查
            List list2 = new ArrayList<String>();
            list2.add(1);
    

    该代码没有任何报错 ;

    在这里插入图片描述





    五、完整代码示例




    1、泛型类 / 方法


    /**
     * 泛型类
     *  该 T 类型作为参数使用
     *  T 是参数化类型 , 可以由外部传入
     *
     * @param <T>
     */
    public class Student<T> {
    
        private String name;
        private int age;
        /**
         * 该数据的类型未知
         *  使用泛型表示 , 运行时确定该类型
         */
        private T data;
    
        public Student(String name, int age, T data) {
            this.name = name;
            this.age = age;
            this.data = data;
        }
    
        /**
         * 该方法不是泛型方法
         *  该方法是普通方法 , 返回值类型是 T 类型
         * @return
         */
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        /**
         * 泛型方法 , 是将某个类型作为参数传入
         *      方法指定泛型 , 写法如下 ;
         *
         * 该方法是泛型方法
         *      方法指定了 2 个泛型
         *      泛型个数 , 泛型的个数可以有很多个
         *      多个泛型之间 , 使用逗号隔开
         *
         * 泛型方法指定的泛型 T 与类中的泛型 T 没有任何关系
         *      这两个 T 可以是不同的类型
         *
         * 泛型方法中定义的泛型 T
         *      与参数类型的 T
         *      返回值类型的 T
         *      方法内部的 T
         *      都是同一个类型
         *
         * 与泛型类中的 T 完全没有关系
         *
         * @param <T>
         * @param <A>
         * @return
         */
        public <T, A> T getData2(T arg){
            T data = arg;
            return data;
        }
    
        public <T> T getData4(T arg){
            T data = arg;
            return data;
        }
    
        /**
         * 如果静态方法中使用类 类中的泛型
         *      这种使用时错误的
         *
         * 如果必须在 静态方法 中使用泛型 T
         *      则该泛型 T 必须是静态方法的泛型
         *      不能是类的泛型
         *
         * @param arg
         * @return
         */
        public static <T> T getData3(T arg){
            T data = arg;
            return data;
        }
    }
    

    2、main 函数


    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) {
            // 指定 泛型类 的泛型为 String 类型
            //      那么在该类中凡是使用到 T 类型的位置 , 必须是 String 类型
            //      泛型类的 泛型声明 , 使用时在 类名后面 声明
            Student<String> student = new Student("Tom", 16, "Cat");
            String data = student.getData();
    
    
            // 如果不 指明泛型类型
            //      则 泛型类型 默认为 Object 类型
            Student student1 = new Student("Tom", 16, "Cat");
            // 获取的 泛型类型的变量也是 Object 类型 , 需要强转为 String
            String data1 = (String) student1.getData();
    
            // 使用 <?> 通配符作为泛型
            //      默认将泛型指定为 Object 类型
            Student<?> student2 = new Student("Tom", 16, "Cat");
            String data2 = (String) student1.getData();
    
            // 泛型的安全检查
            // 推荐写法
            Student<String> student3 = new Student<>("Tom", 16, "Cat");
            // 不推荐写法
            Student student4 = new Student<String>("Tom", 16, "Cat");
    
            // 指定 泛型方法 的泛型类
            //      泛型方法 的泛型声明 , 在调用时 方法名的前面 声明
            student.<String, Integer>getData2("Mouse");
    
            // 泛型方法 中 也可以不声明泛型类型
            //      传入的参数是 泛型 T 类型
            //      如果给传入参数设置 String , 隐含将泛型 T 设置为 String 类型
            String data3 = student.getData2("Mouse");
    
    
            // 编译器 在 编译期 进行检查
            List<String> list1 = new ArrayList<>();
            list1.add(1);
    
            // 编译器 在 编译期 不进行检查
            List list2 = new ArrayList<String>();
            //list2.add(1);
        }
    }
    
    展开全文
  • 泛型 泛型简介 泛型可以理解为参数化类型,主要作用在类,方法和接口上。 Java泛型 与 C++ 模板 : Java 中的泛型 , 是仿照 C++ 中的模板开发的 , 目的是...泛型类 : 类 也可以有参数 , 将 类型 作为 参数 传入类中 ; 泛

    泛型

    泛型简介

    1. 泛型可以理解为参数化类型,主要作用在类,方法和接口上。
    2. Java泛型 与 C++ 模板 : Java 中的泛型 , 是仿照 C++ 中的模板开发的 , 目的是让开发者可以写出通用,灵活的代码 。
    3. 伪泛型 : Java中的泛型 , 是伪泛型 , Java 泛型开发好之后 , 在编译阶段就将泛型相关的信息消除了 , 不会泛型留到运行时。

    泛型类型 :

    • 泛型方法 : 方法有参数 , 方法的参数 可以指定成一些 泛型 ;
    • 泛型类 : 类 也可以有参数 , 将 类型 作为 参数 传入类中 ;
    • 泛型接口 : 接口 的 参数 , 也可以是泛型 ;

    将类型传入泛型方法 , 泛型类, 泛型接口中 , 可以动态地指定一些类型 ;
    泛型的作用 :

    • 安全检查 : 在编译阶段 , 就可以进行 代码检查, 将更少的错误带到运行时 ;
    • 避免强转 : 避免类型的强转导致不必要的安全问题 ;
    • 提高性能 : 使用泛型可以提高 Java 的性能 ;

    泛型类

    泛型类 : 在类名后面使用声明泛型 , 则在该类中, 可以使用该泛型类型 T 类型 ;特别注意 , 该类中的 如下2个方法不是泛型方法 ; 其中的参数 , 返回值类型是T , 但这个T是作为一个正常的类型使用的 , 并不是声明在方法 中的泛型 ;
    如果类,接口,方法是泛型类, 泛型接口,泛型方法, 则该类 , 接口 , 方法必须由 修饰 , 有个带尖括号的 T ;

        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    

    完整的泛型类

    /**
     * 泛型类
     *  该 T 类型作为参数使用
     *  T 是参数化类型 , 可以由外部传入
     *
     * @param <T>
     */
    public class Student<T> {
    
        private String name;
        private int age;
        /**
         * 该数据的类型未知
         *  使用泛型表示 , 运行时确定该类型
         */
        private T data;
    
        public Student(String name, int age, T data) {
            this.name = name;
            this.age = age;
            this.data = data;
        }
    
        /**
         * 该方法不是泛型方法
         *  该方法是普通方法 , 返回值类型是 T 类型
         * @return
         */
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }
    

    泛型方法

    泛型方法 : 在方法的返回值前, 使用 声明泛型的方法 , 是泛型方法 ; 将某个类型作为参数传入 ;
    泛型个数 : 该方法是泛型方法, 且指定了2个泛型 , 泛型的个数可以有很多个, 多个泛型之间 , 使用逗号隔开 ;
    泛型方法 与 泛型类 中的泛型 :
    泛型不同 : 泛型方法指定的泛型T与 类中的泛型T没有任何关系 , 这两个T 可以是不同的类型 ;
    泛型相同 : 泛型方法中定义的泛型T , 与参数类型的T , 返回值类型的T , 方法内部的T , 都是同一个类型 ;

    /**
     * 泛型类
     *  该 T 类型作为参数使用
     *  T 是参数化类型 , 可以由外部传入
     *
     * @param <T>
     */
    public class Student<T> {
    
        private String name;
        private int age;
        /**
         * 该数据的类型未知
         *  使用泛型表示 , 运行时确定该类型
         */
        private T data;
    
        public Student(String name, int age, T data) {
            this.name = name;
            this.age = age;
            this.data = data;
        }
    
        /**
         * 泛型方法 , 是将某个类型作为参数传入
         *      方法指定泛型 , 写法如下
         *
         * 该方法是泛型方法
         *      方法指定了 2 个泛型
         *      泛型个数 , 泛型的个数可以有很多个
         *      多个泛型之间 , 使用逗号隔开
         *
         * 为方法指定的泛型 T 与类中的泛型 T 没有任何关系
         *      这两个 T 可以是不同的类型
         *
         * 泛型方法中定义的泛型 T
         *      与参数类型的 T
         *      返回值类型的 T
         *      方法内部的 T
         *      都是同一个类型
         *
         * 与泛型类中的 T 完全没有关系
         *
         * @param <T>
         * @param <A>
         * @return
         */
        public <T, A> T getData2(T arg){
            T data = arg;
            return data;
        }
    }
    

    静态方法的泛型

    静态方法泛型 : 如果静态方法中使用了类中的泛型T, 作为参数或返回值 , 这种使用时错误的 ;
    如果必须在静态方法中使用泛型T, 则该泛型T必须是静态方法的泛型 , 不能是类的泛型 ;
    错误用法:
    错误用法正确用法 :
    正确用法

    泛型类与泛型方法完整示例

    /**
     * 泛型类
     *  该 T 类型作为参数使用
     *  T 是参数化类型 , 可以由外部传入
     *
     * @param <T>
     */
    public class Student<T> {
    
        private String name;
        private int age;
        /**
         * 该数据的类型未知
         *  使用泛型表示 , 运行时确定该类型
         */
        private T data;
    
        public Student(String name, int age, T data) {
            this.name = name;
            this.age = age;
            this.data = data;
        }
    
        /**
         * 该方法不是泛型方法
         *  该方法是普通方法 , 返回值类型是 T 类型
         * @return
         */
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        /**
         * 泛型方法 , 是将某个类型作为参数传入
         *      方法指定泛型 , 写法如下 ;
         *
         * 该方法是泛型方法
         *      方法指定了 2 个泛型
         *      泛型个数 , 泛型的个数可以有很多个
         *      多个泛型之间 , 使用逗号隔开
         *
         * 泛型方法指定的泛型 T 与类中的泛型 T 没有任何关系
         *      这两个 T 可以是不同的类型
         *
         * 泛型方法中定义的泛型 T
         *      与参数类型的 T
         *      返回值类型的 T
         *      方法内部的 T
         *      都是同一个类型
         *
         * 与泛型类中的 T 完全没有关系
         *
         * @param <T>
         * @param <A>
         * @return
         */
        public <T, A> T getData2(T arg){
            T data = arg;
            return data;
        }
    
        /**
         * 如果静态方法中使用类 类中的泛型
         *      这种使用时错误的
         *
         * 如果必须在 静态方法 中使用泛型 T
         *      则该泛型 T 必须是静态方法的泛型
         *      不能是类的泛型
         *
         * @param arg
         * @return
         */
        public static <T> T getData3(T arg){
            T data = arg;
            return data;
        }
    }
    
    展开全文
  • 浅谈c# 泛型类的应用

    2021-01-01 06:02:25
    泛型类泛型类封装不是特定于具体数据类型的操作。 泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等。 像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。对大多集合类...
  • 泛型的定义: 在定义的时候并不会设置的属性和方法的参数的具体类型,而是在实际用的时候再定义。它存在的意义是帮我们在编译期间检查我们的类型是否正确。 //定义一个Point class Point{ private Object x...

    泛型的定义:

    在定义类的时候并不会设置类的属性和方法的参数的具体类型,而是在类实际用的时候再定义。它存在的意义是帮我们在编译期间检查我们的类型是否正确。

    //定义一个Point类
    class Point{
        private Object x;
        private Object y;
    
        public Object getX() {
            return x;
        }
    
        public void setX(Object x) {
            this.x = x;
        }
    
        public Object getY() {
            return y;
        }
    
        public void setY(Object y) {
            this.y = y;
        }
    }
    
    public class Generic {
        public static void main(String[] args) {
            //创建Point类对象
            Point point = new Point();
            //定义X和Y
            point.setX("东经80度");
            point.setY("北纬20度");
            //转成字符串类型
            String x = (String) point.getX();
            String y = (String) point.getY();
            //打印
            System.out.println("x = "+x);
            System.out.println("y = "+y);
        }
    }
    

    我们先定义一个Point类,其中的X和Y属性我们都用定义为Object类,在使用的时候转成字符串,再进行打印。
    在这里插入图片描述

    但是当我们setY的时候给了它一个整数,但是后面转换成字符串的时候,编译器并没有个我们提示类型错误,只有到运行的时候在产生报错。
    在这里插入图片描述
    告诉我们34行产生类型转化错误,所以就产生类泛型,目的是可以帮助我们在编译器期间就可以告诉我们类型错误,及时修改!

    泛型类:

    基本语法:

    class exampleClass<T>{
    }

    这里的尖括号中的T表示类型参数,可以指代任何类型。
    这里的T可以用任意符号代替,但是java中会给出了一些标准。

    T:代表一般的类
    E:代表Element元素和Exception异常
    K:代表key
    V:代表Value,通常会配合K一起使用(只能出现一个K,K有它对应的Value,键值对)
    S:代表Subtype子类型

    我们利用泛型类将上面的代码再写一遍

    //定义一个泛型Point类
    class Point<T>{
        private T x;
        private T y;
    
        public T getX() {
            return x;
        }
    
        public void setX(T x) {
            this.x = x;
        }
    
        public T getY() {
            return y;
        }
    
        public void setY(T y) {
            this.y = y;
        }
    }
    
    
    public class Generic {
        public static void main(String[] args) {
            //创建Point类对象
            Point<String> point = new Point<String>();
            //定义X和Y
            point.setX("东经80度");
            point.setY("北纬30度");
            //转成字符串类型
            String x = (String) point.getX();
            String y = (String) point.getY();
            //打印
            System.out.println("x = "+x);
            System.out.println("y = "+y);
        }
    }
    

    和之前的代码没有太多的差距,但是我们再将Y定义成一个int类型的数据看一下效果。
    在这里插入图片描述

    编译器提醒我们在32行出现了错误需要我们进行修改!这就是泛型存在的意义。

    泛型方法:

    基本语句:

    class exampleClass<T>{
          public <E> E exampleMethod(E e){
             System.out.println(e);
             return e;
          }
    }

    第一个<E>表示这个方法是一个泛型方法;
    第二个E表示方法的返回值类型是E;
    括号中的E表示传入的参数的类型是E,这个E被称为是参数化类型。
    泛型类和泛型方法是可以共存的,在泛型类中有泛型方法,他们俩尖括号中的内容不是一定要相同的,泛型方法的参数类型是单独的 ,与泛型类无关!

    泛型接口:

    基本语法:

    interface IMessage<T>{
    public void print(T t);
    }

    子类实现这个接口:
    (1)子类仍然是泛型类:

    //定义一个泛型接口
    interface IMessage<T>{
        //抽象方法
        public void print(T t);
    }
    //定义一个类实现泛型接口
    class MessageImpl1<T> implements IMessage<T>{
        //覆写泛型接口的方法
        @Override
        public void print(T t) {
            System.out.println(t);
        }
    }
    

    (2)子类给出具体类型(子类就不是泛型类了):

    //给出具体类型的类就不是泛型类了
    class MessageImpl2 implements IMessage<Integer>{
        //覆写接口方法
        @Override
        public void print(Integer integer) {
            
        }
    }
    

    通配符:

    问号通配符:<?>
    当我们定义了一个泛型类,在写一个方法的时候,要将这个泛型类当做参数传入,但是我们这是不能确定这个泛型类的具体类型,所以就有了问号通配符,帮我们接受这个泛型类包含的所有数据类型。

    //泛型类
    class exampleClass2<T>{
        T t;
        //定义fun方法
        //利用问号通配符,接收泛型类所包含的所有数据类型
        public static void fun(exampleClass2<?> exampleClass){
            System.out.println(exampleClass);
        }
    }
    

    但是用问号通配符的方法不可以修改泛型类对象的值,因为我们在这是不知道该属性的类型,所有不能进行修改。我们只能获取它的值,不能修改
    在这里插入图片描述
    这里77行我们试图修改,编译器就会提醒有错误。

    上限通配符:<? extends A>

    //泛型类
    class exampleClass3<T>{
        T t;
        //上限通配符
        public static void fun(exampleClass3<? extends Number> exampleClass3){
            System.out.println(exampleClass3);
        }
    }
    

    上限通配符与问号通配符的不同就是让问号继承了一个父类,这个这个方法只会接受这个父类及其子类的类型。
    这里也是不清楚该方法具体传入的参数的类型,所以也是只能获取不能修改
    在这里插入图片描述
    95行修改时报错。
    下限通配符:<? super B>

    //泛型类
    class exampleClass4<T>{
        T t;
        //下限通配符
        public static void fun(exampleClass4<? super Number> exampleClass4){
            System.out.println(exampleClass4);
        }
    }
    

    下限通配符表示方法只能接收该类及其所有的父类的类型。
    这里我们清楚所有的传入数据不是当下这个就是它的父类,所以可以通过向上转型进行修改,这里是一个天然的向上转型。
    在这里插入图片描述
    这里我们在修改的时候就不会报错。

    三种通配符的使用特点:
    1、三种通配符都可以用在方法上
    2、只有上限通配符还可以用在泛型类和泛型接口的声明上
    3、问号通配符和上限通配符只能获取数据不能修改
    4、只有下限通配符可以对元素进行修改

    类型擦除:

    泛型只存在于编译阶段,当进入JVM中所有的泛型内容都会被擦除。普通泛型擦除为Object;有泛型上限的擦除为相应的泛型上限;有泛型下限的,擦除为相应的反省下限。反省的存在就只是为了在编译阶段帮助程序员检查类型错误的,所以在运行是它的意义就失去了。

    展开全文
  • 泛型的使用泛型类使用方法泛型类继承泛型接口使用方法泛型接口实现类泛型方法使用方法静态泛型方法所属类为泛型类/泛型接口 前言     我们在平时的开发当中基本上无时无刻都在使用泛型,尤其是涉及到集合、...
  • 自定义泛型类

    2022-01-15 15:21:18
    一、关于自定义泛型类、泛型接口 二、自定义泛型类泛型接口的注意点 三、泛型方法 1.以下的三个方法都不是泛型方法 2.泛型方法:在方法中出现了泛型结构,泛型的参数与类的泛型参数没有任何关系,换句话说,泛型...
  • 通过反射获得指定的父类的泛型参数的实际类型
  • Java 泛型 一、概述 Java 泛型(generics)是 JDK 1.5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。 1.1 什么是泛型泛型,即参数化类型。 一提到参数,...
  • 1泛型的类型参数只能是类类型包括自定义类不能是简单类型 2同一种泛型可以对应多个版本因为参数类型是不确定的不同版本的泛型类实例是不兼容的 3泛型的类型参数可以有多个 4泛型的参数类型可以使用extends语句例如...
  • 自定义泛型类1. 使用泛型类2. 子类继承泛型类4. 泛型方法 1. 泛型的提出 List中默认的类型是Object,当我们向List中传入数字和字符串的时候可以执行,但是当要输出的时候就让人头疼。这时候泛型就出来了,可以指定...
  • 对于框架设计者来说,便捷的代码,是很重要的一部分。 反射和泛型是一种重要的解决途径。 此代码是一个生成泛型对象的类。...希望能帮助那些为查找泛型构造器、非静态内部泛型类的对象生成而烦恼的童鞋。
  • JAVA泛型-泛型类的继承

    千次阅读 2021-10-20 21:38:50
    1.泛型类的继承语法 1.1 方式一 :子类也是泛型类 1.子类的泛型类型要和父类的泛型类型一致 class GenericChild<T> extends GenericFather<T> 2.子类的泛型类型要包含父类的泛型类型 class ...
  • 泛型Java 泛型Java 泛型是什么泛型类泛型类的格式泛型类举例泛型方法泛型方法的格式泛型方法举例泛型接口泛型接口的格式泛型接口举例 Java 泛型 Java 泛型是什么 官方定义: 泛型是Java SE 1.5的新特性,泛型的本质...
  • 泛型允许我们使用类型参数Type parameter,它用一个自定义的标识符(T、V、E)来...在使用泛型类时(区别于定义泛型类时 泛型允许我们使用类型参数Type parameter,它用一个自定义的标识符(T、V、E)来代表一个类型,...
  • Java泛型类

    2021-03-05 19:24:21
    Java泛型类声明除了类名之后是类型参数部分,其它看起来像非泛型类声明。泛型类的类型参数部分可以有一个或多个类型参数,它们之间用逗号分隔。这些类称为参数化类或参数化类型,因为它们接受一个或多个参数。语法...
  • 【Java泛型】泛型类

    2022-01-19 22:49:27
    一、泛型类 1.泛型类的定义语法: Class 类名称<泛型标识,泛型标识...> { private 泛型标识 变量名; ...... } 2.常用的泛型标识,T、E、K、V import java.util.ArrayList; public class Demo { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 315,722
精华内容 126,288
关键字:

泛型类

友情链接: Desktop.rar