Java学习笔记_26_泛型概述

                                                               泛型概述

在Java中存入容器中的对象再取出时需要转换类型,因为对象加入容器会被转换成Object类型,而取出时要转换成实际类型。但向  下类型转换都 是存在潜在危险的,因此应该尽量避免它们。

 Java的泛型:

所谓泛型就是在定义(类、方法、形参、成员变量等等)的时候,指 定它们为通用类型,也就是数据类型可以是任意类型。

泛型为提高大型程序的类型安全和维护带来了很大的潜力。

使用泛型的目的:

· 努力将运行时异常转换成编译时的错误,减少运行时异常的数量。

· 解决模板编程的问题。

1. 泛型的声明:

在定义泛型类的时候,在<>中定义形式类型参数,例如:

Class TestJava<K, V>、Class TestList<E>、Class TestVector<T>,

其中

K:键,比如映射的键。

V:值,比如Set、List、Map中的值。

E:异常类。

T : 泛型。

在实例化泛型对象的时候,一定要在类名后面指定类型参数的值,如:

List<String> list = new ArrayList<String>():

2. 泛型的使用:

1>消除类型的转换:

下面是消除类型转换的例子:

<span style="font-size:14px;">import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;

 public class CollectionsTest {

	public static void main(String[] args) {
		// 声明ArrayList对象 ,且list中只能存储String类元素
		List<String> list = new ArrayList<String>();
		// 向数组列表中添加元素
		list.add("1abc");
		list.add("2def");
		list.add("3hij");
		list.add("4klm");
		// 取得list元素并输出,无须类型转换
		System.out.print("输出第四个元素:");
		String str = list.get(3);
		System.out.println(str);
		System.out.println("\n输出列表中的所有元素:");
		for (String s : list) {
			System.out.println(s);
		}
		System.out.println();
		// 声明一个HashMap对象,指定键的类型为Integer、值的类型为String
		Map<Integer, String> map = new HashMap<Integer, String>();
		// 向对象中添加元素
		map.put(1, "zhao");
		map.put(2, "qian");
		map.put(3, "sun");
		map.put(4, "li");
		// 取得键集
		Set<Integer> keys = map.keySet();
		// 由键取得对应的值,并输出
		System.out.println("输出: key=value");
		for (Integer i : keys) {
			String value = map.get(i);
			System.out.println(i + "=" + value);
		}
	}
 }</span>

输出结果:

输出第四个元素:4klm

输出列表中的所有元素:

1abc

2def

3hij

4klm

输出: key=value

1=zhao

2=qian

3=sun

4=li

注:

·属性中使用集合时不指定泛型,默认为 <Object>,如定义属性: List<Object> list=null;

· 泛型不同的引用不能相互赋值。

· 加入集合中的对象类型必须与指定的泛型类型一一致。

2>限制泛型中类型参数的使用: 

· <?>: 允许所有泛型的引用调用。

· <? Extends Number>: 只允许泛型为Number及Number子类的引用调用。

· <? Super Number>: 只允许泛型为Number及Number父类的引用调用。

· <? Extends Comparable>: 只允许泛型为实现Comparable接口的实现类的引用调用。

注:

· 方法参数中使用集合时不指定泛型默认为<?>.

· 方法参数中<? Extends Number&Comparable>这种修饰符是不  支持的。

下面的例子演示限制类型的参数的范围:

<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;

public class CollectionsTest {

	public static void main(String[] args) {
		List<String> l1 = new ArrayList<String>();
		l1.add("China");
		List<Object> l2 = new ArrayList<Object>();
		l2.add(99);
		List<Number> l3 = new ArrayList<Number>();
		l3.add(3.3);
		List<Integer> l4 = new ArrayList<Integer>();
		l4.add(83);
		List<Double> l5 = new ArrayList<Double>();
		l5.add(93.67);
		printView(l1);//String类型的泛型对象
		printView(l2);//Object类型的泛型对象
		printView(l3);//Number类型的泛型对象
		printView(l4);//Integer类型的泛型对象
		printView(l5);//Double类型的泛型对象
	}
	//方法参数中使用集合时不指定泛型,默认为<?>
	@SuppressWarnings("rawtypes")
	private static void printView(List list) {
		for (Object o : list) {
			System.out.println(o);
		}
	}
} </span>

输出结果:

China

99

3.3

83

93.67

(1)当上面例子中的方法变为:

<span style="font-size:14px;"> //允许所有的泛型的引用调用
   @SuppressWarnings("rawtypes")
  private static void printView(List<?> list) {
	 for (Object o : list) {
		 System.out.println(o);
	 }
  }</span>

时,输出结果:

China

99

3.3

83

93.67

 可见输出结果是不变的。

(2)当上面例子中的方法变为:

<span style="font-size:14px;">//允许Number及Number的自类的引用调用
	@SuppressWarnings("rawtypes")
	private static void printView(List<? extends Number> list) {
		for (Object o : list) {
			System.out.println(o);
		}
	}</span>

此时需要注释掉两行:

<span style="font-size:14px;"> // printView(l1);//String类型的泛型对象
  // printView(l2);//Object类型的泛型对象</span>

运行,

输出结果:

3.3

83

93.67

(3)当上面例子的方法变为:

<span style="font-size:14px;"> //只允许实现了Comparable接口的类的引用调用
	@SuppressWarnings("rawtypes")
	private static void printView(List<? extends Comparable> list)
    {
		for (Object o : list) {
			System.out.println(o);
		}
	}</span>

此时需要注释掉两行:

<span style="font-size:14px;">// printView(l2);//Object类型的泛型对象
 //	printView(l3);//Number类型的泛型对</span>

运行,

输出结果:

China

83

93.67

(4)当上面的例子的方法变为:

<span style="font-size:14px;">// 只允许Number和Number的父类的引用调用
	@SuppressWarnings("rawtypes")
	private static void printView(List<? super Number> list) {
		for (Object o : list) {
			System.out.println(o);
		}
	}
</span>

此时需要注释掉三行:

<span style="font-size:14px;">//	printView(l1);// String类型的泛型对象
 //	printView(l4);// Integer类型的泛型对象
 //	printView(l5);// Double类型的泛型对象</span>

运行,

输出结果:

99

3.3

3>泛型的方法(也被称为Java中的多态):

在类的定义中添加一个形式类型参数列表,可以将类泛型化。方法也 可以被泛型化,不管它们所在的类是不是泛型化的。

泛型方法的格式为:

 修饰符 泛型 返回类型 方法名 参数表 抛出的异常

 泛型的样式有如下几种:

· <T>: 允许所以泛型的引用调用。

· <T extends Number>: 只允许泛型为Number及Number子类的引用调用。

· <T extends Comparable>: 只允许泛型为实现了Comparable接口的实现类的引用调用。

· <T extends Number&Comparable>: 只允许泛型为即是Number及Number子类又实现了Comparable几接口的

实现类的引用调用。

 注:泛型方法中 <? super Number>这种修饰符是不支持的。

下面是泛型方法使用的例子:

<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;

public class CollectionsTest {

	public static void main(String[] args) {
		//声明各类的对象
		List<String> l1 = new ArrayList<String>();
		List<Object> l2 = new ArrayList<Object>();
		List<Number> l3 = new ArrayList<Number>();
		List<Integer> l4 = new ArrayList<Integer>();
		List<Double> l5 = new ArrayList<Double>();
		//创建各类的数组
		String[] a1 = new String[1];
		a1[0] = "a1";
		Object[] a2 = new Object[1];
		a2[0] = "Object";
		Number[] a3 = new Number[1];
		a3[0] = 3;
		Integer[] a4 = new Integer[1];
		a4[0] = 4;
		Double[] a5 = new Double[1];
		a5[0] = 5.5;
		//将相同类的数组copy到对象
		copyFromArray(l1, a1);
		copyFromArray(l2, a2);
		copyFromArray(l3, a3);
		copyFromArray(l4, a4);
		copyFromArray(l5, a5);
		//显示对象元素
		printView(l1);
		printView(l2);
		printView(l3);
		printView(l4);
		printView(l5);
	}
    //显示方法
	private static void printView(List<?> l) {
		for (Object o : l) {
			System.out.println(o);
		}
	}
    //copy的方法
	private static <T> void copyFromArray(List<T> l, T[] a) {
		for (T o : a)
			l.add(o);
	}
}</span>

输出结果:

a1

Object

3

4

5.5

4>泛型类:

 泛型类的写法:

<span style="font-size:14px;">class Person<E> {
	public void show(E e) {
		System.out.println(e);
	}

	public E get() {
		return null;
	}
 }</span>

编写泛型类的时候要注意:

· 静态方法中不能使用类的泛型,原因是泛型类中的泛型在创建类的对象时被替换成确定的类型。

静态方法可以通过类名直接访问,而Java是一种强类语言,没有类型的变量或对象是不允许存在的,

所以静态方法中不能使用类的泛型。

· 不要创建泛型类的对象,因为泛型类有可能是一个接口或抽象类,如果不是接口或抽象类则可以创建。

· 不能在Catch字句中使用泛型,因为编译时,如果try子句抛出的 是一检查的异常,编译器无法确定Catch能否不活这个异常。

下面是演示泛型类创建的技巧的例子:

 类TestGenrics中的代码:

<span style="font-size:14px;">public class TestGenrics {
	public static void main(String[] args) {

		@SuppressWarnings({ "rawtypes" })
		MyClass<?> test = new MyClass();
		test.show();

		MyClass<String> str = new MyClass<String>();
		str.method("323");
		str.show();

		MyClass<Integer> i = new MyClass<Integer>();
		i.method(323);
		i.show();
	}
 } </span>

泛型类MyClass<T> 中的代码:

<span style="font-size:14px;"> class MyClass<T> {
	private T t;

	public void method(T t) {
		this.t = t;
	}

	public T method1() {
		return null;
	}

	public void show(){
		System.out.println(t);
	}
 }</span>

输出结果:

null

323

323

Java学习笔记_26_泛型概述

时间: 2024-10-20 14:06:12

Java学习笔记_26_泛型概述的相关文章

黑马程序员——JAVA学习笔记九(泛型)

1,    泛型机制是JAVA5才支持,使用泛型机制编写的代码比那些杂乱地使用Object变量,然后再强制类型转换的代码具有更好的安全性和可读性. 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用,在泛型出来以前,泛型程序设计是继承Object来实现的.但是有缺点:1,当获取一个值必须要强制类型转换.2,没有类型检查错误,运行时才会出错.泛型提供了类型参数,解决了此问题.   2,    定义泛型类(generic class).格式: public class Pair<T, U>

java学习笔记10--泛型总结

java学习笔记系列: java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/archimedes/p/java-study-note10.html,转载

java学习笔记12--异常处理

java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/arch

java学习笔记 第二篇 核心技术(二)

第十四章 集合类 集合类用来存放对象的引用.继承关系如下图: 14.1 Collection 接口 是层次结构中的根接口,构成Collection的单位称为元素.Collection接口不能直接使用,但该接口提供了添加元素.删除元素.管理数据的方法. Collection接口常用方法: 14.2 List 集合 包括List接口以及List集合的所有实现类.List集合中的元素允许重复,各元素循序就是对象插入的顺序 1.List接口,两个重要方法: get(int index): 获取指定索引位

java学习笔记 5

随手 看到了这篇关于Java到底哪里出了问题的文章,笑傻了23333 “Java developers just can’t help themselves it seems - give em an inch, and next thing you know you’re looking at a OO hierarchy 15 layers deep and instantiating a hammer hammer factory.” 继承 Java中的继承用extends,所有的继承都是

Java学习笔记(2015.7.27~7.31)

Java学习笔记(2015.7.27~7.31) Java 课堂 Java学习笔记(2015.7.27~7.31) 小技巧 常用方法 1.List另一个子类--LinkedList 2.数组的常用方法 3.排序 1.二分法查找 2.数组转换为List 3.可变参数Type ... param (了解) 1.容器Collection 2.自动拆装箱(了解) 3.JDK增强for循环(了解) 4.泛型(掌握) 5.iterator与for在迭代中的区别 1.概念:保存多个对象的对象. 2.JDk为什

java学习笔记之面向对象static,final关键字

java学习笔记之面向对象static,final关键字 一.static关键字 1.概述: static静态的,被static修饰的成员属于类,不属于单个对象,被所有对象所共享,存在静态区中,静态的成员优先于对象加载到内存中. 2.statc修饰成员的使用方式:(被static修饰的成员变量有默认值) /* 1.可以通过对象直接使用,不推荐使用 2.通过类名调用静态成员 类名.静态成员变量 类名.静态成员方法 */ 3.static的特点 /* 1.在同一个类中,静态成员只能访问静态成员,非静

Java学习笔记3-操作符

Java基本操作符:+.-.*./.%.=.==.!=.+=.-=. 优先级:先乘除后加减,如果是连接符+号会优先往前匹配,比如 a+++++b,会被解释称 a++ ++ +b,所以会报错,需要自行使用括号隔离为 (a++) + (++b). 对象的引用如果赋值给了对象的引用后,2 个对象将指向同一个引用,有一个对象的引用重新赋值后将同时影响到另一个对象,比如 ClassName classA = new ClassName(); ClassName classB = new ClassName

Java学习笔记_25_Collections类

25.Collections类: Collections类是一个工具类,用来对集合进行操作,它主要是提供一些排序算法,包括随机排序.反相排序等. Collections类提供了一些静态方法,实现了基于List容器的一些常用算法. Collections的一些方法列表: · void sort(List): 对List内的元素进行排序. · void shuffle(List): 对List内的元素随机排序. · void reverse(List): 对List内的元素进行逆序排列. · voi