Java基础巩固----泛型

注:参考书籍:Java语言程序设计。本篇文章为读书笔记,供大家参考学习使用

 

1.使用泛型的主要优点是能够在编译时而不是在运行时检查出错误,提高了代码的安全性和可读性,同时也提高了代码的复用性。

1.1如何理解泛型的使用提高了代码的安全性?

答:例如这样一段代码:

ArrayList<Date> arrayList = new ArrayList<Date>();

arrayList.add(new Date());

arrayList.add(“data”);

这段代码在编译时会报错,因为ArrayList只能存储同一种类型的数据。

如果这段代码更改为非泛型类型的话,如下:

ArrayList arrayList = new ArrayList();

arrayList.add(new Date());

arrayList.add(“data”);

而这段代码在编译时就不会报错,而是在运行时会出现出错,所以,使用泛型可以提高代码的安全性。

1.2如何理解提高了代码的复用性?

答:例如,创建一个泛型公共方法,则这个方法就可以处理多种数据类型,不必再为每一种数据类型单独的编写方法,故提高了代码的复用性。

 

2.定义泛型类

方法:在类名后面添加两个尖括号,在尖括号中填写类型形参(此时的类型形参一般使用T或者E,当然也可以使用其他的标识),多个形参之间使用逗号隔开,例如:

public class GenericStack<T>{

}

警告:假设创建一个上面类的对象,形式为:GenericStack<String> genericStack = new GenericStack<String>();这可能会误导我们认为GenericStack的构造函数为public GenericStack<T>();其实这是错误的,它的构造函数应该为:public GenericStack();

 

可以定义一个类或者一个接口作为泛型或者接口的子类型。例如,在Java API中,java.lang.String类被定义为实现了Comparable接口,如下所示:

public class String implements Comparable<String>

 

3.定义泛型方法

格式:在方法的返回类型前添加一对尖括号,然后在尖括号中填写类型形参,多个类型形参之间使用逗号隔开。为了调用泛型方法,需要将实际类型放在尖括号内作为方法名的前缀,例如:

GenericMethodDemo.<Integer>print(integers);

GenericMethodDemo.<String>print(strings);

 

4.受限的泛型类型:将泛型指定为另一种类型的字类型

例如:public <E extends GeometricObject> boolean equalArea(){}

注:非受限类型<E>和受限类型<E extends Object>是一样的。

 

5.原始类型:不使用类型参数的泛型类称为原始类型(raw type);

 

6.通配泛型:通配泛型有3中形式:?、?extends T、? super T。

第一种形式称为非受限通配(unbounded wildcard),它和? extends Object效果一样

第二种形式称为受限通配(bounded wildcard),它表示T或者T的一个未知字类型

第三种形式称为下线通配(lower-bound wildcard),表示T或T的一个未知父类型

 

7.泛型消除和对泛型的限制

          泛型是使用一种称为类型消除的方法来实现的。编译器使用泛型类型消息来编译代码,但是随后会消除它。因此,泛型信息在运行时是不可用的。这种方法可以使泛型代码向后兼容使用原始类型的遗留代码。

          由于泛型类型在运行时被消除,因此,对于如何使用泛型类型是有一些限制的:

                限制1:不能使用new E();

                          因为运行时执行的是new E(),但是运行时泛型类型E是不可用的。

                限制2:不能使用new E[],不能使用泛型类型参数创建数组

                         E[] elements = new E[capacity];

                        可以通过创建一个Object类型的数组,然后将它的类型转换为E[]来规避这个限制,如下所示

                        E[] elements = (E[])new Object[capacity];

                        但是这种使用类型转化的方式会导致一个免检的编译警告。该警告之所以出现是因为编译器无法确保在运行时类型转换是否成功。这种类型的编译警告是对java泛型的限制,也是无法避免的。

不允许使用泛型类创建泛型数组,例如,下面的代码是错误的:

ArrayList<String>[] list = new ArrayList<String>[10];

可以使用下面的代码来规避这种限制:

ArrayList<String>[] list = (ArrayList<String>[])new ArrayList[10];

这样会得到一个警告。

 

                限制3:在静态环境下不允许类的参数是泛型类型

由于泛型类的所有实例都有相同的运行时类,所以泛型类的静态变量和方法是被它的所有实例所共享的。因此,在静态方法中、数据域、或者初始化语句中,为了类而引用类型参数是非法的。例如,下面的代码是非法的:

public class Test<E>{

        public static void m(E ol){    //非法

           

        }

        public static E ol; //非法

        static{

               E o2;//非法

        }

}

                 限制4:异常类不能是泛型的

Java基础巩固----泛型

时间: 2024-08-09 10:43:42

Java基础巩固----泛型的相关文章

java基础之泛型用法

1.什么是泛型 泛型是java中保障类型安全的一种机制.它通过对变量类型的假设,实现变量类型的进行限制,从而在一定程度上保证程序编译时变量类型的安全.反之,如果没有泛型,这些假设则只存在于程序员的大脑中,这样会导致类型转换的异常在程序运行时才被发现. //不用泛型 List list1 = new ArrayList(); list1.add(1); Object o = list1.get(0); //返回Object类型对象 Integer i = (Integer) o; //需预先知道类

Java基础:泛型

Java的泛型是什么呢, 就是类型的参数化,这得类型包括方法参数和返回值,也就是原本该是确定类型的地方换成了变量,把类型的确定时间向后延迟了. 在之前,学过"重载"的概念,重载是什么呢,举例来说 public class Test{ // 处理整型数据 void receive(int i) { System.out.println("Received one int data"); System.out.println("i="+i); } /

java基础之泛型的继承

关于泛型的基本介绍和理解请参考以下几篇文章,或查询更多资料: 泛?型?与?泛?型?继?承 泛型(包括泛型抽象类的继承) 泛型的继承测试 本篇以简单的List<>方式来进行说明. ArrayList<Object>继承了List<Object>, ArrayList<String>没有继承List<Object> List<?>等价于List<? extends Object> 请参考以下代码: /** * author D

Java基础:泛型详解

泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用.什么是泛型?为什么要使用泛型? 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参).泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型).也

JAVA基础_泛型

什么是泛型 泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉"类型"信息,是程序的运行效率不受影响,对于参数化的泛型类型,getClass()方法返回值和原始类型完全一样.由于编译生成的字节码会擦除泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,然后再调用add()方法即可 GenericDemo.java public class GenericDemo

黑马程序员——【Java基础】——泛型、Utilities工具类、其他对象API

一.泛型 (一)泛型概述 1.泛型:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制. 2.泛型技术是给编译器使用的技术,用于编译时期,确保类型的安全. 3.泛型的擦除:运行时,会将泛型去掉,生成class文件中的是不带泛型的,这个称为“泛型的擦除”.擦除泛型的原因是为了兼容运行时的类加载器. 4.泛型的好处:(1)将运行时期出现的问题ClassCastException,转移到了编译时期.方便于程序员解决问题,让运行时期问题减少.安全.(2)避免了强制转换的麻烦. 5.泛

Java基础:泛型及其擦除性、不可协变性

转载请注明出处:jiq?钦's technical Blog 1泛型语法: 泛型类: class ClassName<T>{} 泛型方法:public <T> void f(T x){} 基本指导原则:如果使用泛型方法可以取代将整个类泛型化,那么就应该使用泛型方法,因为它可以让事情更加清楚. 2为什么使用泛型? 在Java SE1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的

java基础入门-泛型(1)

为什么需要使用泛型? 1.代码复用 2.保证类型安全 3.编程的便利 第一部分,先说说代码复用 1)建立一个Animal的父类 package com.ray.test; public class Animal { private String name="Animal"; public String getName() { return name; } public void setName(String name) { this.name = name; } } 2)建立连个Ani

java基础知识 泛型

泛型 泛型类型的参数类型必须是引用类型如 ArrayList<int> list = new ArrayList<int>();  //错误 ArrayList<Integer> list = new ArrayList<Integer>();  //正确list.add(5);  //正确  自动打包(装箱)机制int i = list.get(0); //正确,如果元素是包装类型,如Integer,Double,Character,可以直接将这个元素赋给