java进阶之泛型

     2022-04-01     216

关键词:

泛型的优点

  1. 泛型类型可以提高可靠性和可读性
  2. 泛型可以参数化类型
  3. 泛型可以让我们在编译时而不是在运行时检测出错误

泛型类或方法允许用户指定可以和这些类或方法一起工作的对象类型(相容的对象)
泛型类ArrayList、泛型接口Comparable
从JDK1.5开始,Java允许定义泛型类、泛型接口、泛型方法

泛型实例化

技术图片
泛型就是限制对象的数据类型

泛型的正确使用

举个栗子吧

创建一个存储字符串的线性表(ArrayList)

ArrayList<String> list = new ArrayList<>();

现在就只能向该线性表中添加字符串

list.add("a");

如果试图向其中添加非字符串类型,就会产生编译错误

list.add(new Person("张三",23));

当没有使用泛型时,编译通过,运行也通过,即可以添加任何元素,但这样做在遍历元素进行相关操作时会产生隐藏的bug。

?
泛型类型必须是引用数据类型,不能使用基本数据类型。

错误示范

ArrayList<int> list = new ArrayList<>();

正确示范

ArrayList<Integer> list = new ArrayList<>();
list.add(5);      //自动装箱

?
使用泛型对数据类型进行限制后,无须类型转换就可以从一个线性表中获取一个值,因为编译器已经知道了这个元素的类型。

使用泛型前

ArrayList list = new ArrayList();
list.add("Jone");              //自动提升为Object类型
list.add("Smith");
String s = (String)(list.get(0));//将Object类型转为String类型

使用泛型后

ArrayList<Double> list = new ArrayList<>();
list.add(5.5);          //5.5 is automatically converted to new Double(5.5)
list.add(3.0);          //3.0 is automatically converted to new Double(3.0)
Double doubleObject = list.get(0);  //No casting is needing
double d = list.get(1);             //Automatically converted to double

定义泛型类和接口

可以为类或者接口定义泛型。当使用容器类来创建对象,或者使用容器类或接口来声明引用变量时,必须指定具体的类型。

利用ArrayList模拟堆栈结构,使用泛型对元素类型进行限制

public class Stack<E>{
        //构造方法
        public Stack(){}

        //创建数组列表,存储元素的数据类型为E,需导包alt+shift+O
        private ArrayList<E> list = new ArrayList<>();

        //返回栈中的元素数目
        public int getSize(){
                return list.size();
        }

        //返回栈顶元素
        public E peek(){
                return list.get(getSize() - 1);
        }

        //返回并移除栈顶元素
        public E pop(){
                E o = list.get(getSize() - 1);
                list.remove(getSize() - 1);
                return o;
        }

        //添加一个新元素到栈顶
        public void push(E o){
                list.add(o);
        }

        //如果栈为空,就返回true
        public boolean isEmpty(){
                return list.isEmpty();
        }

        @Override
              public String toString(){
                return "stack : " + list.toString();
        }
}

若使用LinkedList模拟堆栈结构,可以用getLast()、removeLast()、addLast()方法
上面自定义类的构造方法不是public Stack<E>(){},而是public Stack(){}

泛型可能会有多个参数,应将所有参数一起放在尖括号中,并用逗号分隔开,比如<E1,E2,E3>
可以定义一个类或接口作为泛型类或者泛型接口的子类型
例如

public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence

泛型方法

可以为静态方法定义泛型类型

public clas GenericMethodDemo{
        public static void main(String[] args){
                Integer[] integers = {1,2,3,4,5};
                String[] strings = {"London","Paris","New York","Austin"};

                GenericMethodDemo.<Integer>print(integers);
                GenericMethodDemo.<String>print(strings);
         }
         public static <E> void print(E[] list){
         for(int i = 0;i<list.length;i++){
                 System.out.print(list[i]+" ");
                 System.out.println();
        }
}

为了声明泛型方法,将泛型类型<E>置于方法声明中关键字static之后

public static <E> void print(E[] list)

为了调用泛型方法,需要将实际类型放在尖括号内作为方法名的前缀。例如,

GenericMethodDemo.<Integer>print(integers);
GenericMethodDemo.<String>print(strings);

简单调用

print(integers);
print(strings);

 

可以将泛型指定为另外一种类型的子类型,这样的泛型类型称为受限的。例如下面所示的代码用以测试两个几何对象是否具有相同的面积。受限的泛型类型将E指定为GeometricObject的泛型子类型。此时必须传递两个GeomericObject的实例来调用equalArea

public class BoundedTypeDemo{
    public static void main(String[] args){
        Rectangle rectangle = new Rectangle(2,2);
        Circle circle = new Circle(2);
        System.out.println("Same area?" + equalArea(rectangle,circle));
    }
    public static <E extends GeometricObject> boolean equalArea(
            E object1,E object2){
        return object1.getArea()==object2.getArea();
    }
}

非受限泛型类型<E>等同于<E extends Object>
为了定义一个类为泛型类型,需要将泛型类型放在类名之后,例如,GenericStack
为了定义一个方法为泛型类型,要将泛型类型放在方法返回类型之前,例如,void max(E o1,E o2)

java基础之泛型

泛型类容器类应该算得上最具重用性的类库之一。 publicclassContainer{ privateStringkey; privateStringvalue; publicContainer(Stringk,Stringv){ key=k; value=v; } publicStringgetKey(){&nbs 查看详情

java之泛型

泛型的理解:泛型示例:泛型语法:泛型注意事项自定义泛型例如:自定义泛型接口泛型方法普通类中定义泛型方法:没有<T,R…>不是泛型方法,而是方法使用了泛型习题:泛型的继承和通配符ÿ... 查看详情

java之泛型擦除

泛型擦除  在严格的泛型代码里,带泛型声明的类总应该带着类型参数。但为了与老的Java代码保持一致,也允许在使用带泛型声明的类时不指定类型参数。如果没有为这个泛型类指定泛型参数,则该类型参数被称作一个原始... 查看详情

java之泛型

泛型出现的原因:集合中可以存储各种对象,会被自动被提升为Object类型,当我们在取出每一个对象时,需要进行相应的操作。但如果集合中存储着不同类型的元素,则会出现类型转换异常ClassCastException,所以在存储时,必须明... 查看详情

java解惑之泛型

1、首先看下面的代码:两种方式的比较:  >>>不使用泛型时:可以添加不同类型的数据,容易导致安全问题@Testpublicvoidtest01(){Listlist=newArrayList();list.add("张三丰");list.add(100);System.out.println(list);}  >>>使用 查看详情

十:java之泛型

【定义】一、泛型的定义主要有下面两种:    在程序编码中一些包括类型參数的类型,也就是说泛型的參数仅仅能够代表类。不能代表个别对象。(这是当今较常见的定义)在程序编码中一些包括參数的类。其參... 查看详情

java初谈之泛型

/***泛型与c++的模版有异曲同工之妙*泛型是面向对象的**函数基本使用格式< T>返回值函数名(){}//可以是任意的大写字母不一定非是T*类基本使用格式classclassname<T>{} 以及classclassname<Textendinterface&implements>{}**使用... 查看详情

java基础知识(java之泛型)

   什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的... 查看详情

typescript入门手册之泛型(代码片段)

...点关照大家感兴趣的点,欢迎同学留言交流,在进阶之路上,共勉!👍star本项目给作者一点鼓励吧📚系列 查看详情

typescript入门手册之泛型(代码片段)

...点关照大家感兴趣的点,欢迎同学留言交流,在进阶之路上,共勉!👍star本项目给作者一点鼓励吧📚系列 查看详情

java基础之泛型(代码片段)

泛型genericity格式:<自定义泛型无意义大写英文字母占位符>例:<T>Type<E>Element<K>Key<V>value泛型可以在方法,类,接口中使用泛型在方法中使用使用静态方法的泛型格式:publicstatic<T>返回值类型[自定义... 查看详情

java基础--泛型之泛型参数

泛型机制常用的参数有3个:“?”代表任意类型。如果只指定了<?>,而没有extends,则默认是允许任意类。extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类。super关键字声明了... 查看详情

2022-08-01java之泛型枚举多线程

(目录)一、泛型1.什么是泛型泛型是JavaSE5出现的新特性,泛型的本质是类型参数化或参数化类型,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。2.泛型的意义一般的类和方法,只能使用具体... 查看详情

第三节:java数据结构预备知识之泛型

上一节内容讲时间和空间复杂度:(王道408考研数据结构)第一章绪论-第二节2:算法的时间复杂度和空间复杂度注意:泛型是Java语法中比较难掌握的部分,所以了解即可文章目录一:什么是泛型二:泛型语法(1)定义·(2)使用... 查看详情

java之泛型解说

1、集合中只能装入引用数据类型,不能装入基本数据类型。如,装入int类型的数值123会自动装箱。2、开发人员装入集合的数据类型不确定,所以它被设计成可以装入所有的Object。3、新的问题产生,装入集合的数据丢失原来的数... 查看详情

java基础之泛型的使用

为什么要使用泛型首先我们先来看一段演示代码,如下所示,1publicstaticvoidmain(String[]args){2Listlist=newArrayList();3list.add("abc");4list.add(123);5list.add(HashMap.class);67System.out.println(list.get(0));8}第2行,List里面的内容类型是Obj 查看详情

java重要技术(19)泛型之泛型的使用方法

1.1. 泛型的用法参数化类型比如Sample<T>中的类型参数T可以用于构造函数的参数的类型,方法的返回值的类型,画着方法的参数的类型,属性字段的类型等。publicclassGenericParameterTest{//参数化类型T,可以为String,Integer等引用... 查看详情

java遗珠之泛型的作用(代码片段)

泛型总共有三个作用编译时进行更强大的类型检查编译时错误比运行时错误更好发现和处理消除类型转换Listlist=newArrayList();list.add("hello");Strings=(String)list.get(0);使用泛型之后去掉转换List<String>list=newArrayList<Str... 查看详情