`

JDK5新特性之一“泛型”总结

    博客分类:
  • java
阅读更多
泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastException的可能。
在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型。

泛型特点:只要编译的时候没有问题,执行的时候肯定没有问题。

泛型之前:
类别定义时的逻辑完全一样,只是里面成员变量的类型不同。
如果需要多个相似的类,需要定义多个文件,不同的只是变量的类型,而逻辑是完全一样的。



以后使用集合的时候必须要使用泛型(可以避免很多强制类型转换)
迭代器迭代过程中迭代器也要加上泛型


以下是各种集合类在遍历的时候使用泛型的标准写法,以后把这个作为标准都这么写:

package com.shengshiyuan4;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ArrayListTest {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		for (int i = 0; i < list.size(); i++) {
			String value = list.get(i);
			System.out.println(value);
		}

		for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
			String value = iter.next();
			System.out.println(value);
		}
	}
}


package com.shengshiyuan4;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetTest {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("aa");
		set.add("bb");
		set.add("cc");

		for (Iterator<String> iter = set.iterator(); iter.hasNext();) {
			String value = iter.next();
			System.out.println(value);
		}

		System.out.println("--------------------------------");
		Set<People> set2 = new HashSet<People>();
		set2.add(new People("zhangsan", 20, "beijing"));
		set2.add(new People("lishi", 30, "shanghai"));
		set2.add(new People("wangwu", 40, "guangzhou"));

		for (Iterator<People> iter = set2.iterator(); iter.hasNext();) {
			People people = iter.next();
			String name = people.getName();
			String address = people.getAddress();
			int age = people.getAge().intValue();
			System.out.println(name + "," + age + "," + address);
		}
	}
}

class People {
	private String name;
	private Integer age;
	private String address;

	public People(String name, Integer age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + ((age == null) ? 0 : age.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final People other = (People) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (age == null) {
			if (other.age != null)
				return false;
		} else if (!age.equals(other.age))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

}


package com.shengshiyuan4;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapTest {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("1", "aa");
		map.put("2", "bb");
		map.put("3", "cc");

		Set<String> set = map.keySet();
		for (Iterator<String> iter = set.iterator(); iter.hasNext();) {
			String key = iter.next();
			String value = map.get(key);
			System.out.println(key + ";" + value);
		}

		Set<Map.Entry<String, String>> set2 = map.entrySet();
		for (Iterator<Map.Entry<String, String>> iter = set2.iterator(); iter
				.hasNext();) {
			Map.Entry<String, String> entry = iter.next();
			String key = entry.getKey();
			String value = entry.getValue();
			System.out.println(key + ";" + value);
		}
	}
}



现在您有这么一个需求,您希望有一个参考名称foo可以接受下面所有的实例。
Foo = new GenericFoo<ArrayList>();
Foo = new GenericFoo<LinkedList>();
简单的说,实例化类型持有者时,它必须是实现List的类别或其子类别,要定义这样一个名称,您可以使用‘?’通配字元,并使用“extends”关键字限定类型持有者的型态。



在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型,的那是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。比如List<T extends List>,需要注意的是这里不管是类还是接口都要用extends关键字。


当没有指定泛型继承的类型或接口时,默认使用T extends Object,所以默认情况下任何类型都可以作为参数传入。


使用<?>或是<? Extends SomeClass>的声明方式,意味着您只能通过该名称来取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的话,那么您就得记得取回的实例是什么类型,然后转换为原来的类型方可进行操作,这就失去了使用泛型的意义。



重点比较下面两个类中泛型使用的各种情况,下面这两种情况有的时候很难区分,需要重点仔细查看这两个类:

package com.shengshiyuan4;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

//定义的时候没有明确泛型类型的范围
public class GenericTest<T> {
	private T foo;

	public T getFoo() {
		return foo;
	}

	public void setFoo(T foo) {
		this.foo = foo;
	}

	public static void main(String[] args) {
		// 表示ge是一个空的引用,它的类型是GenericTest,并且里面的泛型可以是实现了List接口的类型
		// 申明引用变量的时候,表示这个引用可以指向什么类型的一个对象,表示可以指向类型为GenericTest的类并且里面的泛型类型必须实现了List接口
		// 表示可以指向的一个泛型对象的类别到底是什么(在使用泛型的时候引用本身到底是什么类型的,这种方式并没有限定类里面的泛型是什么类型的,不像下面那种方式在开始就限定了)
		GenericTest<? extends List> ge = null;

		ge = new GenericTest<ArrayList>();
		ge = new GenericTest<LinkedList>();

		GenericTest<? extends Map> ge2 = null;

		ge2 = new GenericTest<HashMap>();
		ge2 = new GenericTest<TreeMap>();

		// 表示ge3可以指向GenericTest对象,里面的泛型要在继承层次当中位于List上面(这个用的比较少)
		GenericTest<? super List> ge3 = null;
		ge3 = new GenericTest<Collection>();

		GenericTest<String> ge4 = new GenericTest<String>();
		ge4.setFoo("hello world");

		GenericTest<? extends Object> ge5 = ge4;
		System.out.println(ge5.getFoo());
		ge5.setFoo(null);
		System.out.println(ge5.getFoo());

		// 下面这种用法是错误的,原因是使用<?>或是<? Extends SomeClass>的声明方式,意味着您只能通过该名称来取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的话,那么您就得记得取回的实例是什么类型,然后转换为原来的类型方可进行操作,这就失去了使用泛型的意义。
		// ge5.setFoo("welcome");

	}
}


package com.shengshiyuan4;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

//申明定义类的时候就指定好泛型类型的范围
//表示在构建这个泛型对象的时候具体的泛型类别可以是什么样的类型(定义类的时候就指定好了泛型的类别)
public class ListGenericFoo<T extends List> {
	private T[] fooArray;

	public T[] getFooArray() {
		return fooArray;
	}

	public void setFooArray(T[] fooArray) {
		this.fooArray = fooArray;
	}

	public static void main(String[] args) {
		ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
		ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();

		LinkedList[] linkedList = new LinkedList[10];

		foo1.setFooArray(linkedList);

		ArrayList[] arrayList = new ArrayList[10];

		foo2.setFooArray(arrayList);

		// 下面这种写法就是错误的
		// ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();
	}
}


分享到:
评论

相关推荐

    JDK1.5新特性泛型_深入研究.doc

    ### JDK1.5新特性泛型深入研究 #### 一、引言 随着软件工程的发展,类型安全成为了程序设计中的一个重要考量因素。Java作为一种广泛使用的编程语言,在其发展历程中不断引入新的特性以满足日益增长的需求。JDK1.5...

    JDK5一些新特性关于枚举泛型等

    总结起来,JDK 5的枚举类型和泛型特性提高了代码的安全性,降低了类型转换错误,增强了代码的可读性和可维护性。它们是现代Java编程不可或缺的部分,对于任何Java开发者来说,理解和掌握这些特性都是非常重要的。

    jdk5.zip_java 泛型_jdk5 泛型_泛型

    Java 泛型是Java编程语言中的一个重要特性,它在JDK 5版本中引入,显著提高了代码的类型安全性和重用性。泛型允许程序员在类、接口和方法中使用类型参数,使得容器(如ArrayList、LinkedList等)可以保存特定类型的...

    JDK10新特性之var泛型和多个接口实现方法

    在JDK10中,Java引入了两个重要的新特性,分别是var关键字的使用以及更灵活的接口实现方式。这两个特性都是为了提升代码的可读性和灵活性。 首先,我们来看var泛型。var关键字并不是一个新的数据类型,而是局部变量...

    jdk1.5新特性,泛型,for:each

    泛型是JDK 1.5引入的一项革命性特性,它允许在类、接口和方法中声明类型参数,从而增强了代码的类型安全性。在使用泛型之前,集合框架中的元素只能被定义为Object类型,导致在添加和取出元素时需要进行强制类型转换...

    JDK7新特性(完整篇)

    Java Development Kit (JDK) 7 是 Java 编程语言的一个重大更新,包含了多项新特性,旨在提升开发者的效率、程序的性能以及对现代计算环境的支持。以下是对这些特性的详细解析: 1. **JDK7新特性&lt;一&gt;概述** JDK7的...

    jdk7新特性jdk8新特性

    Java 8最重要的特性之一就是引入了lambda表达式,它使得函数式编程风格成为可能。Lambda表达式可以更简洁地表示匿名函数,比如: ```java Collections.sort(list, (a, b) -&gt; a.compareTo(b)); ``` #### 2. Stream ...

    jdk1.5的新特性泛型的实例代码

    Java开发工具包(JDK)1.5引入了一项重大改进,那就是泛型(Generics)。泛型是Java编程语言中的一个关键特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。通过泛型,...

    JDK5,JDK8新特性.ppt .ppt

    Java 语言的发展历程中,JDK 5 和 JDK 8 引入了许多重要的新特性,极大地提升了编程...总的来说,JDK 5 和 JDK 8 中的泛型以及其他新特性,显著增强了 Java 语言的表达能力和安全性,为开发人员带来了更好的编程体验。

    Jdk15泛型的实现

    GJ是一个支持泛型特性的Java编译器插件,为后续的泛型技术发展奠定了基础。到了JDK1.4,通过JSR#14的支持,泛型技术以插件的形式得到了更广泛的采纳,尽管当时的Java标准库并未针对泛型进行全面的改写。直至JDK1.5,...

    jdk1.5新特性关于动态参数,泛型等

    泛型是 JDK 1.5 最重要的改进之一,它允许在定义集合类时指定元素类型,从而在编译时就能进行类型检查。这样可以防止运行时的 ClassCastException,增加代码的类型安全性。例如,使用泛型,我们可以创建一个只存储 ...

    JDK1.5新特性

    2. **泛型**:泛型是1.5最重要的新特性之一,它允许在类、接口和方法中使用类型参数,增强了类型安全性和代码重用性。泛型可以限制集合元素的类型,避免了类型转换错误。 3. **枚举类(enum)**:之前的Java中,...

    jdk1.5新特性

    ### JDK 1.5 新特性详解 #### 泛型编程 **定义与作用:** 泛型编程是 Java 1.5 引入的一项重要特性,它允许开发者在编译时进行类型安全检查,从而避免了运行时可能出现的类型转换异常。通过在编译阶段检查类型安全...

    Jdk1_5中的新特性 --泛型 (详细版)

    容器不能放基类型不好,接着说泛型没用。而恰恰Jdk1.5中解决了这些问题,所以感叹之余,把这篇文章改一下,详细的说说泛型

    jdk6新特性介绍

    Java Development Kit (JDK) 6是Java编程语言的一个重要版本,它在2006年发布,带来了许多新特性和改进,提升了开发者的效率和应用程序的性能。在这个版本中,Oracle(当时还是Sun Microsystems)引入了对JavaScript...

    详细介绍JDK1.5的各种新特性

    1. **泛型(Generics)**:泛型是JDK1.5引入的最大变革之一。它允许在类、接口和方法中使用类型参数,提高了代码的类型安全性和重用性。泛型帮助程序员在编译时检查类型错误,避免了运行时的强制类型转换,使代码...

    jdk5新特性

    泛型是JDK 5中最显著的新特性之一,允许在类、接口和方法中声明类型参数,提高了类型安全性和代码重用性。泛型避免了强制类型转换,减少了运行时错误,并使代码更易于理解和维护。 2. **自动装箱与拆箱...

    JDK 5 新特性PDF

    JDK 5的发布标志着Java语言进入了一个新的发展阶段,通过引入上述新特性,极大地改善了Java程序的编写效率和代码质量。这些新特性不仅让开发人员能够编写出更安全、更简洁的代码,也为后续版本的发展奠定了坚实的...

    JDK5_新特性

    Java开发工具包(JDK)5.0,代号Tiger,是Java语言的一个重要版本,带来了许多新特性和改进,极大地提升了开发效率和代码的可读性。以下是JDK5.0的主要新特性: 1. **自动封箱与自动解封**: 在JDK5.0之前,Java中...

    jdk7.0新特性

    jdk7.0新特性中最重要的特点之一是对集合的支持。该特性使得创建List、Set、Map等集合类型变得更加简洁。例如,创建一个List类型的集合,可以使用以下语句:List&lt;String&gt; list = ["item"];这样简洁的写法可以大大...

Global site tag (gtag.js) - Google Analytics