Consider the following classes (written before the introduction of generics in JDK 5.0), designed to describe various kinds of media that a library might contain:
public class Library { private List resources = new ArrayList(); public void addMedia(Media x) { resources.add(x); } public Media retrieveLast() { int size = resources.size(); if (size > 0) { return resources.get(size - 1); } return null; }}public class Media {}public class Book extends Media {}public class Video extends Media {}public class Newspaper extends Media {}
Given the above classes, imagine a program that uses them to catalog information about a collection of books (and only books). Here is a code snippet from that program:
//A Library containing only BooksLibrary myBooks = new Library();...Book lastBook = (Book)myBooks retrieveLast();
Type casting the return value from the
retrieveLast
method to
Book
is necessary, so the compiler knows what kind of object is returned and what kinds of operations can be performed on that object. Even though the programmer may be certain that only
Book
objects will be returned, the compiler does not know this. If a programming error did result in, say, a
Video
being stored in
myBooks
and then returned here, the cast would cause an unexpected exception to be thrown at runtime.
This is the primary reason that generic types and methods (often referred to, simply, as generics) were added to the Java language — to add compile-time type checking so the compiler can detect mismatched types at compile time, rather than runtime, when an exception is thrown.
Here is the same Library
class with a few simple changes (shown in bold), modified to use generics:
public class Library<E> { private List resources = new ArrayList<E>(); public void addMedia(E x) { resources.add(x); } public E retrieveLast() { int size = resources.size(); if (size > 0) { return resources.get(size - 1); } return null; }}//The Media classes require no changes to use generics —//please refer to the original example.
Library is now a
generic type with a single
type parameter E
. When using a generic type, specify a
type argument for each of its type parameters. A
Library
containing only
Book
objects, for example, would be written as
Library<Book>
. This is an example of a
parameterized type
. The code snippet now looks like this:
Library<Book> myBooks = new Library<Book>();...Book lastBook = myBooks retrieveLast();
The type cast and the comment are no longer needed because the
Library
instance has been constrained to deal with
Book
objects. The compiler now understands that this particular instance of
Library
contains
Book
s. If the compiler detects that the
Library
is being used inappropriately — trying to add or retrieve a
Newspaper
, for example — it generates an error.
Later on our imaginary program includes the following line of code:
myBooks.addMedia(myFavoriteBook);
Without generics, the compiler couldn't warn you if
myFavoriteBook
is of the wrong type. If it is a
String
, for example, a runtime exception would occur somewhere down the road after someone invokes
retrieveLast
. These sorts of errors can be especially hard to debug, since the runtime error may occur at a point in the code far removed from the actual programming error that caused it. With generics, the compiler calls out the error right away. You find out about the programming error immediately, and are shown exactly where the problem lies.
You can further refine the declaration of Library
to use Library<E extends Media>
. The compiler will enforce the constraint that a Library
can only contain Media
objects (and not, say, Number
s).
If you use any of the Java programming libraries that deal with groups of data, such as classes or interfaces that deal with collections, lists, arrays, and vectors, you will notice that they make extensive use of generics.
Note: When compiling code that refers to generics, you might encounter a message like this: Note: MyFile.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.
This error means that you have bypassed generics and have lost the benefit of compile-time type checking. You should fix your code to make full use of generics and take advantage of compile-time type checking. As mentioned in the text of the sample error, using the -Xlink:unchecked
javac
option gives you the most information available about unchecked or type unsafe operations.
This covers a simple case of using a generic class. Subsequent sections go into generic types in more detail and touch on generic methods.
分享到:
相关推荐
1. 泛型简介:泛型是在.NET 2.0中引入的,它允许开发者定义和实现可以使用任意类型作为参数的类、接口和方法。这样,无需为每种数据类型创建单独的类实例,从而减少了代码重复和类型转换的开销。 2. 类型参数与约束...
#### 引言:Java泛型简介 Java的泛型是Java 1.5引入的一项重要特性,它允许开发者在类型上进行抽象,从而编写出更加通用且类型安全的代码。本教程旨在深入浅出地介绍Java泛型的基本概念和用法。即便你对其他语言...
1. **泛型简介**: 泛型是.NET框架2.0引入的新特性,其核心目标是提供类型安全性和运行时效率。通过泛型,我们可以编写一次代码,然后在不同的数据类型上重用,无需进行强制转换,减少了类型不匹配的错误可能性。 ...
.NET Framework 2.0引入了新的语言特性和性能改进,如Generics、Partial Types、匿名方法等。 2. **C# 2.0**:Visual Studio 2005主要支持的语言之一,C# 2.0在C# 1.0的基础上增加了许多新特性,如迭代器、匿名方法...
在本教程中,你可能会学习如何定义和使用类型类,如何利用`GHC.Generics`和`generics-sop`进行类型级别的操作,以及如何编写能够处理多种数据类型的泛型函数。此外,你还将接触到如何安装和使用`generics-sop`库,...
### TypeScript简介与特性详解 #### 一、TypeScript的起源与发展 TypeScript 是一种由微软开发的开源编程语言,它的诞生旨在解决JavaScript在处理大型项目时所遇到的问题。随着Web应用变得越来越复杂,传统的...
### Java程序员5.0升级版本简介 #### 一、引言 随着信息技术的快速发展,Java作为全球最流行的编程语言之一,其每一次版本更新都备受关注。Java 2平台标准版(J2SE)5.0的发布被视为Java发展史上的一个重要里程碑。...
"Swift 初始化语法糖,更简介的语法实现组件初始化.zip"这个开源项目显然旨在分享如何使用这些简洁的语法来初始化组件。 1. **默认构造器(Default Initializers)** Swift提供了一个默认构造器,当类没有定义任何...
6. **范型(Generics)**: 范型是Java中的一种类型参数化机制,允许在类、接口和方法中使用类型参数。它们增强了类型安全,确保在编译时期就能捕获潜在的类型错误。范型通过泛型类型参数 `<T>`来表示,如`List<T>`...
内容简介:The ultimate guide on the newest version of C#, from an unparalleled team of authors Get ready for the next release of Microsoft's C# programming language with "Professional C# 2010," the ...
#### 泛型(Generics) Swift支持泛型编程,使得开发者可以编写灵活、可重用的代码。通过泛型,开发者可以在不指定具体数据类型的情况下定义函数和类型,这大大提高了代码的复用性和通用性。 #### 协议(Protocols...
Throughout, Gottschling demonstrates how to write clear and expressive software using object orientation, generics, metaprogramming, and procedural techniques. By the time you’re finished, you’ll ...
### Django REST Framework简介 Django REST Framework(简称DRF)是基于Django的一个高级Web API 框架,它提供了丰富的功能,包括序列化、身份验证、权限控制以及分页,使得开发者能够快速、有效地构建高质量的...
- 简介.txt:可能对整个教程的总体介绍和学习指南。 9. **学习建议** - 按照笔记的章节顺序逐步学习,确保对每个概念都有扎实的理解。 - 结合实践,通过编写代码来巩固理论知识。 - 定期回顾,加深记忆,避免...
一、`drf-flex-fields`简介 `drf-flex-fields`是针对Django Rest Framework的一个扩展,它的主要目标是允许用户在请求时动态地选择返回哪些字段。在默认情况下,DRF会序列化所有模型字段,但有时我们可能只需要部分...
**TypeScript简介** TypeScript是JavaScript的一个超集,由微软开发并维护,旨在提供静态类型检查、面向对象的特性以及更强大的工具支持,以提升大型项目开发的效率和可维护性。它在JavaScript的基础上增加了类型...
.NET Framework 2.0简介 - **核心组件**:包括Common Language Runtime (CLR)、Base Class Library (BCL)、Windows Presentation Foundation (WPF)等。 - **新特性**:如Generics泛型编程、简化的XML处理API、改进...