`
MouseLearnJava
  • 浏览: 465477 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java泛型小结(一)

    博客分类:
  • Java
阅读更多
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。   

泛型的好处是在编译的时候检查类型安全,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

泛型小结将从如下几个方面入手: 通配符号的使用将放入下一篇博文中介绍

  • 泛型的修饰范围
  • 使用&实现多重限制
  • 类型擦除
  • <? super T>, <? extends T>, <?>通配符的使用

泛型修饰的范围   

java 泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 


a) 泛型接口的例子
public interface List<E> extends Collection<E> {
 ...

 Iterator<E> iterator();

 boolean add(E e);

 boolean addAll(Collection<? extends E> c);

 ...
}


b) 泛型类的例子
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    ...
    public Iterator<E> iterator() {
        return new Itr();
    }

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

    ... 

    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    ...
}


c) 泛型方法的语法

[访问权限修饰符][static][final]<类型参数列表>返回值类型 方法名([形式参数列表])
其中,[]内的内容是可选的。

下面举几个Collections工具类中的几个泛型方法例子:

    public static <T> void sort(List<T> list, Comparator<? super T> c) {
	Object[] a = list.toArray();
	Arrays.sort(a, (Comparator)c);
	ListIterator i = list.listIterator();
	for (int j=0; j<a.length; j++) {
	    i.next();
	    i.set(a[j]);
	}
    }



    public static <T extends Comparable<? super T>> void sort(List<T> list) {
	Object[] a = list.toArray();
	Arrays.sort(a);
	ListIterator<T> i = list.listIterator();
	for (int j=0; j<a.length; j++) {
	    i.next();
	    i.set((T)a[j]);
	}
    }


    public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
        if (comp==null)
            return (T)min((Collection<SelfComparable>) (Collection) coll);

	Iterator<? extends T> i = coll.iterator();
	T candidate = i.next();

        while(i.hasNext()) {
	    T next = i.next();
	    if (comp.compare(next, candidate) < 0)
		candidate = next;
	}
	return candidate;
    }



使用&实现多重限制


如果一个类型有多余一个的限制条件,可以使用&实现多重限制

    public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) < 0)
                candidate = next;
        }
        return candidate;
    }
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) > 0)
                candidate = next;
        }
        return candidate;
    }



类型擦除

类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。


比如:
import java.util.List;

public class TypeErasureTest {

	public void test(List<String> ls) {
		System.out
				.println("Mthod test(List<String> ls) is calling.");

	}

	public void test(List<Integer> ls) {
		System.out.println("Mthod test(List<Integer> ls) is calling.");
	}
}


这段代码无法编译通过




在编译后泛型类型是会被擦除的,在这个重载的例子中,因为参数List<Integer>和 List<String>编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作导致这两个方法的特征签名一样,这样两个相同的方法将不能满足重载,最后导致编译失败。


在编译后所有的泛型类型都会做相应的转化:

  • List<String>, List<Integer>, List<T>擦除后的类型为List
  • List<String>[] 擦除后的类型为List[]
  • List<? extends E>, List<? super E> 擦除后的类型为List<E>
  • List<T extends Serialiable & Clonable> 擦除后为List<Serialiable>
  • 大小: 32.4 KB
2
2
分享到:
评论

相关推荐

    不同Java泛型构造函数的详解

    4. 小结 在本文中,我们讨论了Java中的泛型构造函数,包括非泛型类中的泛型构造函数和泛型类中的泛型构造函数。我们也学习了如何使用泛型构造函数来创建对象。在实际开发中,泛型构造函数可以帮助我们编写更加灵活...

    Java高级程序设计实战教程第四章-Java泛型,4.1 应用场景4.2 相关知识4.3 实施过程4.4 拓展知识4.5 拓展训

    java--4.1 应用场景4.2 相关知识4.3 实施过程4.4 拓展知识4.5 拓展训练4.6 课后小结4.7 课后习题4.8 上机实训

    Java个人学习小结

    ### Java个人学习小结 #### Java发展史及重要里程碑 - **起源与发展**: Java 的起源可以追溯到 1992 年,当时的 Sun Microsystems 公司开发了一种名为 Oak 的编程语言,最初是为了家用电器的智能化而设计的。然而...

    泛型中extends和super的区别Java系列2021.pdf

    在Java泛型编程中,extends和super关键字用于限制类型参数的范围。PECS原则是一个重要的原则,用于指导泛型编程。了解extends和super关键字的区别,并遵循PECS原则,可以帮助你编写更好的泛型代码。

    Java语言基础入门教程 Java实训教程 10.枚举与泛型 共27页.pptx

    **10.1.5 枚举小结** - 枚举是一种引用类型,因为它隐式继承自`java.lang.Enum`类。 - 枚举是JDK 5.0之后新增的特性,使用并不频繁。 - 枚举值是常量,具有默认的`public static final`修饰符。 - 使用枚举类型的...

    JAVA程序:接口小结

    本文档“JAVA程序:接口小结”很可能是对Java接口的全面总结,包含了相关的代码示例,帮助学习者深入理解和运用接口。 接口在Java中的主要特性包括: 1. **接口是完全抽象的**:接口中的所有方法默认都是抽象的,...

    java 解析xml 多级

    DOM解析器会将整个XML文件加载到内存中,形成一个树形结构,适合处理小到中等规模的XML文档。而SAX解析器采用事件驱动的方式,逐行读取XML文件,适合处理大型XML文件以避免内存消耗。 对于多级XML,DOM解析更便于...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    1.6 小结:我们学会了编译和运行一个Java程序! 18 1.7 习题 19 第2章 搭建自己的集成开发环境 20 教学视频:31分钟 2.1 安装集成开发环境 20 2.1.1 集成开发环境有哪些 20 2.1.2 安装Eclipse 21 2.2 Eclipse...

    学习上的一些小结,主要是java和C#等

    本文将深入探讨这两个语言的核心概念,以及它们在实际开发中的应用,同时也会涉及Spring框架,一个在Java生态系统中至关重要的组件。 首先,Java是一种跨平台的面向对象的编程语言,由Sun Microsystems(后被Oracle...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    1.6 小结:我们学会了编译和运行一个Java程序! 18 1.7 习题 19 第2章 搭建自己的集成开发环境 20 教学视频:31分钟 2.1 安装集成开发环境 20 2.1.1 集成开发环境有哪些 20 2.1.2 安装Eclipse 21 2.2 Eclipse...

    疯狂JAVA讲义

    1.9 本章小结 22 本章练习 22 第2章 理解面向对象 23 2.1 面向对象 24 2.1.1 结构化程序设计简介 24 2.1.2 程序的三种基本结构 25 2.1.3 面向对象程序设计简介 27 2.1.4 面向对象的基本特征 28 2.2 UML...

    Java实验--贪心猪小游戏、输入输出流、图形化界面、图书管理系统.docx

    **实验小结:** - 加深了对类的理解。 - 学会了内部类的声明与使用技巧。 - 理解了玩家间的轮转逻辑优化。 --- #### 实验二:输入输出流的应用 **实验目的:** - 掌握文件读写的Java API。 - 学习文本处理及异常...

    Java Methods-The Java Collections Framework.ppt

    Java 集合框架 Java 集合框架是一个强大的框架,提供了...小结 Java 集合框架是一个强大且灵活的框架,提供了丰富的集合类和接口,以方便开发者处理数据。它是 Java 语言的核心组件之一,广泛应用于各种应用程序中。

    java初学者应该阅读的书籍

    ### 小结 通过系统地学习上述书籍,Java初学者将能够建立起全面而深入的知识体系。这些书籍不仅仅是理论知识的堆砌,更重要的是提供了大量实用的代码示例和案例分析,有助于读者更好地理解和掌握Java语言的特点。...

    Java反射机制学习总结

    Java反射机制是Java编程语言中一个强大的工具,它允许程序在运行时动态地获取类的信息并操作类的对象。反射机制的核心在于java.lang.reflect包中的API,主要包括Class类、Constructor类、Method类和Field类。以下是...

    Thinking in java4(中文高清版)-java的'圣经'

    + 和 += 3.14 使用操作符时常犯的错误 3.15 类型转换操作符 3.15.1 截尾和舍入 3.15.2提升 3.16 Java没有“sizeof” 3.17 操作符小结 3.18 总结 第4章 控制执行流程 4.1 true和false 4.2 if-else 4.3 迭代 4.3.1 do-...

    Java面向对象教程

    以上内容只是Java面向对象编程的一小部分,马士兵教授的教程会更深入地探讨这些概念,并结合实例进行讲解,帮助开发者更好地理解和应用面向对象技术。通过学习和实践,你可以掌握创建高效、可维护的Java应用程序的...

    数据结构与算法分析Java语言描述(第二版)

    Java51.4.1 使用Object表示泛型1.4.2 基本类型的包装1.4.3 使用接口类型表示泛型1.4.4 数组类型的兼容性1.5 利用Java5泛性实现泛型特性成分1.5.1 简单的泛型类和接口1.5.2 自动装箱/拆箱1.5.3 带有限制的通配符...

    java/c++区别

    (七) 小结 Java简化了C++的许多复杂性,适合快速开发,但C++的性能和灵活性使其在需要底层控制的场景中更胜一筹。Java的跨平台能力也是其一大优势,而C++更依赖于特定的硬件和操作系统。 总之,Java和C++各有优缺点...

Global site tag (gtag.js) - Google Analytics