Generics泛型的应用
JDK 5 中的泛型
Generics(泛型)
泛型的第一个优点是实现编译时期检查;第二个优点是在使用collection框架的时候不需要cast了。
一、先来了解一下JDK5以前是怎么处理的。
在JDK5之前的Collection框架以Object为参数,这样整个Collection框架可以变得通用,而不是对于每个数据类型都定义一个Collection。
比如,List的add方法: 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>();
虽然String是Object的子类,但是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引入泛型的初衷,也许只是为了创造 容器类 也说不定。 站在类库设计者的角度,...
环境:Windows XP Professional、JDK 1.6、Ant 1.7 说明:Java泛型的动机是为解决类型转换在编译时不报错的问题。另外由于“范型编程”(Generic Programming)的推广,于是2004年JDK 5.0引用范型标准。本例子说明...
在.NET中泛型使用非常频繁,在控制台应用程序中,默认的引入了System.Collection.Generics名称空间,其中就提供了我们经常使用的泛型:List和Dictionary,相信用过它们的都知道它们的强大。还有一种我们经常使用的...
在编译时评估RegEx “模板”的代码,这样您可以在运行应用程序之前知道结果吗? RegEx引擎可以处理O(0)运行时复杂性吗? 缩小的0位(GZip)长度输出? 完全错误并且还没有准备好进行生产吗? 我不是在开玩笑!!...
java arraylist源码泛型示例 Java源代码程序,通过使用应用于ArrayList的用户定义的数据类型来演示泛型概念的示例
AppNote: 显式指定Java泛型方法的返回值和输入参数的类型,使泛型方法在实际应用时,和泛型类,泛型接口一样方便。
9. Swift中的泛型(Generics)是什么?它在编程中有何作用? 10. 在Swift中如何实现多线程编程?请说明在Swift中的多线程处理方法。 11. Swift中的Tuple是什么?它在Swift中的作用是什么? 12. Swift中的访问控制
技术关键词:Rust编程语言、所有权(Ownership)、借用(Borrowing)、生命周期(Lifetimes)、模式匹配(Pattern Matching)、错误处理、泛型(Generics)、并发(Concurrency)、闭包(Closures)、特性(Traits)...
泛型服务这是由生成的模块。 您需要安装SDK才能使用此模块。 。 您还可以从其或了解有关此模块中实现的应用程序的更多信息。设置和测试将您的KBase开发人员令牌添加到test_local/test.cfg并运行以下命令: $ make$ ...
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 ...
.NET 2.0 泛型在实际开发中的一次小应用 C#2.0 Singleton 的实现 .Net Framwork 强类型设计实践 通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: State Server Gems 完整的动态加载/卸载程序集的解决方案 ...
Chapter 12-Generics 新增讨论了委托和接口泛型类型参数的不同。 Chapter 13-Interfaces 无新话题。 Part III – Essential Types Chapter 14-Chars, Strings, and Working with Text 无新话题。 Chapter 15-...
书中提供了大量的实例,可帮助读者快速掌握如何在.NET平台下开发功能强大的ASP.NET应用程序。本书适合有一些基础的ASP.NET初级程序员以及准备迁移到ASP.NET 2.0的编程老手。该书与《ASP.NET 2.0入门经典(第4版)》...
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 ...
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 ...
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 ...
)下面是一个清单: 关键字 用途 deprecation 使用了不赞成使用的类或方法时的警告 unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。 fallthrough 当 Switch ...