`

Generics泛型的应用

阅读更多

Generics泛型的应用

                                      

JDK 5 中的泛型

 

Generics(泛型)

泛型的第一个优点是实现编译时期检查;第二个优点是在使用collection框架的时候不需要cast了。

 

一、先来了解一下JDK5以前是怎么处理的。

JDK5之前的Collection框架以Object为参数,这样整个Collection框架可以变得通用,而不是对于每个数据类型都定义一个Collection

 

比如,Listadd方法: public boolean add(java.lang.Object element)

但是当你使用的时候,get()方法是这样声明的:

public java.lang.Object get(int index)

  throws IndexOutOfBoundsException

请看下面的例子:

List stringList1 = new ArrayList();

stringList1.add("Java 5");

stringList1.add("with generics");

String s1 = (String) stringList1.get(0);

 

一切看起来ok,但是如果这样

List stringList1 = new ArrayList();

stringList1.add("Java 5");

stringList1.add(new Date());

stringList1.add("with generics");

String s1 = (String) stringList1.get(1);

看起来也ok,运行起来就出现

java.lang.ClassCastException: java.util.Date

 

二、应用泛型

正如方法可以接收参数,泛型类型也可以接收参数,这也是为什么generic type也称作 “parameterized type”。用<>angle bracket)将参数传递给泛型。

 

例如:java.util.List,可以写作  List<E> myList,其中E称作类型变量。在JDK5中可以如下实例化:

List<String> myList = new ArrayList<String>();

 

JDK5中,代码可以如下:

           List<String> stringList2 = new ArrayList<String>();

           stringList2.add("Java 5.0");

           stringList2.add("with generics");

           // no need for type casting

           String s2 = stringList2.get(0);

           System.out.println(s2.toUpperCase());

如果你尝试将Date()加入这个List

           List<String> stringList2 = new ArrayList<String>();

           stringList2.add("Java 5.0");

           stringList2.add("with generics");

           stringList2.add(new Date());

           // no need for type casting

           String s2 = stringList2.get(0);

           System.out.println(s2.toUpperCase());

 

系统会提示:

The method add(String) in the type List<String> is not applicable for the arguments (Date)

 

比较前面JDK5之前的处理,已经实现了编译期检查,不会将错误留到运行时候。

 

三、比较JDK5和之前的处理

import java.util.List;

import java.util.ArrayList;

 

public class GenericListTest {

  public static void main(String[] args) {

    // in JDK 1.4

    List stringList1 = new ArrayList();

    stringList1.add("Java 1.0 - 5.0");

    stringList1.add("without generics");

    // cast to java.lang.String

    String s1 = (String) stringList1.get(0);

    System.out.println(s1.toUpperCase());

 

    // now with generics in JDK 5

    List<String> stringList2 = new ArrayList<String>();

    stringList2.add("Java 5.0");

    stringList2.add("with generics");

    // no need for type casting

    String s2 = stringList2.get(0);

    System.out.println(s2.toUpperCase());

  }

}

 

 

下面是一个有趣的应用:

import java.util.ArrayList;

import java.util.List;

public class ListOfListsTest {

  public static void main(String[] args) {

    List<String> listOfStrings = new ArrayList<String>();

    listOfStrings.add("Hello again");

    List<List<String>> listOfLists = new ArrayList<List<String>>();

    listOfLists.add(listOfStrings);

    String s = listOfLists.get(0).get(0);

    System.out.println(s); // prints "Hello again"

  }

}

 

四、泛型进阶

对于没有使用泛型处理的代码,在JDK5中,系统会出现编译警告,提示代码为”raw type”

这是兼容的,如果不想看到这个信息,可以做如下处理:

1 使用 –source 1.4 参数编译。

2 使用@SupressWarnings(“unchecked”) annotaion

3 升级为使用泛型

 

如果你声明一个泛型List<atype>,那么List的实现中,atype可以是如下类型:

1 atype的实例

2 atype子类的实例(如果atype是一个class

3 atype的实现类的实例(如果atype是一个接口)

 

泛型和Java对象一样,都有自己的类型,下面两个就是完全独立,没有关系的:

List<Object> list1 = new ArrayList<Object>();

List<String> list2 = new ArrayList<String>();

 

虽然StringObject的子类,但是List<String>可不是List<Object>的子类。

 

再看下面的代码,

import java.util.ArrayList;

import java.util.List;

 

public class AllowedTypeTest {

  public static void doIt(List<Object> l) {

  }

  public static void main(String[] args) {

    List<String> myList = new ArrayList<String>();

    // this will generate a compile error

    doIt(myList);

  }

}

系统会提示编译错误。

 

为了解决类似的问题,JDK5提出了通配符号(?)List<?>,这个声明意味着List可以接收任何对象。

import java.util.ArrayList;

import java.util.List;

 

public class WildCardTest {

 

  public static void printList(List<?> list) {

    for (Object element : list) {

      System.out.println(element);

    }

  }

  public static void main(String[] args) {

    List<String> list1 = new ArrayList<String>();

    list1.add("Hello");

    list1.add("World");

    printList(list1);

 

    List<Integer> list2 = new ArrayList<Integer>();

    list2.add(100);

    list2.add(200);

    printList(list2);

  }

}

 

特别注意,如果你这样声明就不对了:

List<?> myList = new ArrayList<?>();

 

边界通配符 (bounded wildcards)

 

在泛型中,如果你有一个getAverage方法用来返回平均值,你可能要传递integer,float,double等。那么你将参数设置为List<Number>,但是由于List<Number>List<Integer>List<Double>是不同的类型,所以不行。我们还可以用List<?>,但是这样会降低类型安全,因为List<String>也可能发生。

 

JDK5推出upper bounded ,格式如下:

GenericType <? Extends uppderBoundedType>

请看下面的例子:

import java.util.ArrayList;

import java.util.List;

public class BoundedWildcardTest {

  public static double getAverage(List<? extends Number> numberList)

  {

    double total = 0.0;

    for (Number number : numberList)

      total += number.doubleValue();

    return total/numberList.size();

  }

 

  public static void main(String[] args) {

    List<Integer> integerList = new ArrayList<Integer>();

    integerList.add(3);

    integerList.add(30);

    integerList.add(300);

    System.out.println(getAverage(integerList)); // 111.0

    List<Double> doubleList = new ArrayList<Double>();

    doubleList.add(3.0);

    doubleList.add(33.0);

    System.out.println(getAverage(doubleList)); // 18.0

  }

}

 

It’s so ok

如果在main()

分享到:
评论

相关推荐

    深入Java:Generics泛型

    要是我们所写的代码本身是为了应用于“某种不确定的类型”呢?  这时候轮到 泛型 登场了。  简单泛型  虽然理想远大。但Java引入泛型的初衷,也许只是为了创造 容器类 也说不定。  站在类库设计者的角度,...

    Java 泛型(Generics)使用说明

    环境:Windows XP Professional、JDK 1.6、Ant 1.7 说明:Java泛型的动机是为解决类型转换在编译时不报错的问题。另外由于“范型编程”(Generic Programming)的推广,于是2004年JDK 5.0引用范型标准。本例子说明...

    .NET基础之自定义泛型分析

    在.NET中泛型使用非常频繁,在控制台应用程序中,默认的引入了System.Collection.Generics名称空间,其中就提供了我们经常使用的泛型:List和Dictionary,相信用过它们的都知道它们的强大。还有一种我们经常使用的...

    ts-generics-RegEx-engine:袋装的少数功能仅支持由Typescript泛型编写的RegEx引擎

    在编译时评估RegEx “模板”的代码,这样您可以在运行应用程序之前知道结果吗? RegEx引擎可以处理O(0)运行时复杂性吗? 缩小的0位(GZip)长度输出? 完全错误并且还没有准备好进行生产吗? 我不是在开玩笑!!...

    javaarraylist源码-contoh_generics:Java源代码程序,通过使用应用于ArrayList的用户定义的数据类型来演示

    java arraylist源码泛型示例 Java源代码程序,通过使用应用于ArrayList的用户定义的数据类型来演示泛型概念的示例

    TestMain.java

    AppNote: 显式指定Java泛型方法的返回值和输入参数的类型,使泛型方法在实际应用时,和泛型类,泛型接口一样方便。

    Swift面试题.pdf

    9. Swift中的泛型(Generics)是什么?它在编程中有何作用? 10. 在Swift中如何实现多线程编程?请说明在Swift中的多线程处理方法。 11. Swift中的Tuple是什么?它在Swift中的作用是什么? 12. Swift中的访问控制

    Rust面试必杀技:一网打尽热门问题!.zip

    技术关键词:Rust编程语言、所有权(Ownership)、借用(Borrowing)、生命周期(Lifetimes)、模式匹配(Pattern Matching)、错误处理、泛型(Generics)、并发(Concurrency)、闭包(Closures)、特性(Traits)...

    GenericsService:具有针对Generics对象的获取方法的动态服务

    泛型服务这是由生成的模块。 您需要安装SDK才能使用此模块。 。 您还可以从其或了解有关此模块中实现的应用程序的更多信息。设置和测试将您的KBase开发人员令牌添加到test_local/test.cfg并运行以下命令: $ make$ ...

    2.ASP.NET.2.0.高级编程(第4版) [1/7]

    10.6 System.Collections.Generics 299 10.6.1 泛型的定义 299 10.6.2 泛型列表 300 10.6.3 泛型字典 302 10.6.4 其他泛型集合 303 10.7 集合从.NET 1.1到.NET 2.0的变化 303 10.8 集合和列表总结 303 10.9 ...

    asp.net知识库

    .NET 2.0 泛型在实际开发中的一次小应用 C#2.0 Singleton 的实现 .Net Framwork 强类型设计实践 通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: State Server Gems 完整的动态加载/卸载程序集的解决方案 ...

    CLR via C# 3rd Edition

    Chapter 12-Generics 新增讨论了委托和接口泛型类型参数的不同。 Chapter 13-Interfaces 无新话题。 Part III – Essential Types Chapter 14-Chars, Strings, and Working with Text 无新话题。 Chapter 15-...

    ASP.NET2.0高级编程(第4版)1/6

    书中提供了大量的实例,可帮助读者快速掌握如何在.NET平台下开发功能强大的ASP.NET应用程序。本书适合有一些基础的ASP.NET初级程序员以及准备迁移到ASP.NET 2.0的编程老手。该书与《ASP.NET 2.0入门经典(第4版)》...

    Java SE实践教程 源代码 下载

    3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 68 第4章 数据传送的管道——JAVA I/O 71 4.1 讲解 72 4.1.1 流——Java I/O的基础 72 4.1.2 Java I/O库 72 ...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 68 第4章 数据传送的管道——JAVA I/O 71 4.1 讲解 72 4.1.1 流——Java I/O的基础 72 4.1.2 Java I/O库 72 ...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 68 第4章 数据传送的管道——JAVA I/O 71 4.1 讲解 72 4.1.1 流——Java I/O的基础 72 4.1.2 Java I/O库 72 ...

    @SuppressWarnings

    )下面是一个清单: 关键字 用途 deprecation 使用了不赞成使用的类或方法时的警告 unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。 fallthrough 当 Switch ...

Global site tag (gtag.js) - Google Analytics