Java中泛型的介绍与简单使用

学习目标

掌握泛型的产生意义。

掌握泛型的基本使用。

了解泛型的警告信息及泛型的擦除。

泛型是在JDK1.5之后增加的内容,泛型(Generic)

使用泛型的原因

题目分析:

首先要考虑到,必须建立一好一个表示坐标点的类——Point,此类中有两个属性分别用来表示x坐标和y坐标,但是x和y中所保存的整数类型会有三种(int、float、String),而要想使用一个类型可以同时接收这样的三种类型数据,现在只能使用Object,因为Object类可以接收任何类型的数据,都会自动发生向上转型操作,这样三种数据类型安装以下的方式进行转换:

数字(int) —> 自动装箱成Interger —> 向上转型使用Object接收

小数(float)—> 自动装箱成Float —> 向上转型使用Object接收

字符串(String)—>向上转型使用Object接收

设计Point类

class Point{
	private Object x ;		// 表示X坐标
	private Object y ;		// 表示Y坐标
	public void setX(Object x){
		this.x = x ;
	}
	public void setY(Object y){
		this.y = y ;
	}
	public Object getX(){
		return this.x ;
	}
	public Object getY(){
		return this.y ;
	}
};

public class GenericsDemo01{
	public static void main(String args[]){
		Point p = new Point() ;	// 声明一个Point的对象
		p.setX(10) ;		// 利用自动装箱操作:int --> Integer --> Object
		p.setY(20) ;		// 利用自动装箱操作:int --> Integer --> Object
		int x = (Integer)p.getX() ;	// 取出数据先变为Integer,之后自动拆箱
		int y = (Integer)p.getY() ;	// 取出数据先变为Integer,之后自动拆箱
		System.out.println("整数表示,X坐标为:" + x) ;
		System.out.println("整数表示,Y坐标为:" + y) ;
	}
};

小数表示

class Point{
	private Object x ;		// 表示X坐标
	private Object y ;		// 表示Y坐标
	public void setX(Object x){
		this.x = x ;
	}
	public void setY(Object y){
		this.y = y ;
	}
	public Object getX(){
		return this.x ;
	}
	public Object getY(){
		return this.y ;
	}
};

public class GenericsDemo02{
	public static void main(String args[]){
		Point p = new Point() ;	// 声明一个Point的对象
		p.setX(10.5f) ;		// 利用自动装箱操作:float --> Float --> Object
		p.setY(20.6f) ;		// 利用自动装箱操作:float --> Float --> Object
		float x = (Float)p.getX() ;	// 取出数据先变为Float,之后自动拆箱
		float y = (Float)p.getY() ;	// 取出数据先变为Float,之后自动拆箱
		System.out.println("小数表示,X坐标为:" + x) ;
		System.out.println("小数表示,Y坐标为:" + y) ;
	}
};

字符串表示:

class Point{
	private Object x ;		// 表示X坐标
	private Object y ;		// 表示Y坐标
	public void setX(Object x){
		this.x = x ;
	}
	public void setY(Object y){
		this.y = y ;
	}
	public Object getX(){
		return this.x ;
	}
	public Object getY(){
		return this.y ;
	}
};

public class GenericsDemo03{
	public static void main(String args[]){
		Point p = new Point() ;	// 声明一个Point的对象
		p.setX("东经180度") ;		// String --> Object
		p.setY("北纬210度") ;		// String --> Object
		String x = (String)p.getX() ;	// 取出数据先变为String,之后自动拆箱
		String y = (String)p.getY() ;	// 取出数据先变为String,之后自动拆箱
		System.out.println("字符串表示,X坐标为:" + x) ;
		System.out.println("字符串表示,Y坐标为:" + y) ;
	}
};

以上代码存在很大问题,如果现在假设有以下的程序代码。

class Point{
	private Object x ;		// 表示X坐标
	private Object y ;		// 表示Y坐标
	public void setX(Object x){
		this.x = x ;
	}
	public void setY(Object y){
		this.y = y ;
	}
	public Object getX(){
		return this.x ;
	}
	public Object getY(){
		return this.y ;
	}
};

public class GenericsDemo04{
	public static void main(String args[]){
		Point p = new Point() ;	// 声明一个Point的对象
		p.setX(10) ;			// 利用自动装箱操作:int --> Integer --> Object
		p.setY("北纬210度") ;		// String --> Object
		int x = (Integer)p.getX() ;	// 取出数据先变为Integer,之后自动拆箱
		int y = (Integer)p.getY() ;	// 取出数据先变为Integer,之后自动拆箱
		System.out.println("整数表示,X坐标为:" + x) ;
		System.out.println("整数表示,Y坐标为:" + y) ;
	}
};

传统的实现方法就有可能出现操作不当的情况,本程序就是数据类型不统一造成的。

认识泛型

泛型的使用

泛型可以解决数据类型的安全性问题,它主要的原理,是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值以及参数类型。这样在类声明或实例化的时候只要指定好需要的类型即可。

泛型的定义格式如下:

[访问权限] class 类名称<泛型类型1,泛型类型2,......泛型类型3>{

[访问权限] 泛型类型标识 变量名称;

[访问权限] 泛型类型标识  方法名称(){ };

[访问权限]  返回值类型声明 方法名称(泛型类型标识 变量名称){};

}

泛型对象的定义

类名称<具体类型> 对象名称 = new 类名称<具体类型>();

按照此格式定义一个Point类。

class Point<T>{		// 此处可以随便写标识符号,T是type的简称
	private T var ;	// var的类型由T指定,即:由外部指定
	public T getVar(){	// 返回值的类型由外部决定
		return var ;
	}
	public void setVar(T var){	// 设置的类型也由外部决定
		this.var = var ;
	}
};

写完之后,就可以在对象声明的时候使用了。

class Point<T>{		// 此处可以随便写标识符号,T是type的简称
	private T var ;	// var的类型由T指定,即:由外部指定
	public T getVar(){	// 返回值的类型由外部决定
		return var ;
	}
	public void setVar(T var){	// 设置的类型也由外部决定
		this.var = var ;
	}
};
public class GenericsDemo06{
	public static void main(String args[]){
		Point<String> p = new Point<String>() ;	// 里面的var类型为String类型
		p.setVar("MLDN") ;		// 设置字符串
		System.out.println(p.getVar().length()) ;	// 取得字符串的长度
	}
};

以上是将var变量设置成了String类型,当然也可以设置成Integer,如果设置的内容与指定的泛型类型不一致,则会在编译时就出现错误。

class Point<T>{		// 此处可以随便写标识符号,T是type的简称
	private T var ;	// var的类型由T指定,即:由外部指定
	public T getVar(){	// 返回值的类型由外部决定
		return var ;
	}
	public void setVar(T var){	// 设置的类型也由外部决定
		this.var = var ;
	}
};
public class GenericsDemo07{
	public static void main(String args[]){
		Point<Integer> p = new Point<Integer>() ;	// 里面的var类型为String类型
		p.setVar("MLDN") ;		// 设置字符串
	}
};

这样可以更好的去保护数据类型。

通过泛型就可以直接去修改之前的程序。

class Point<T>{
	private T x ;		// 表示X坐标
	private T y ;		// 表示Y坐标
	public void setX(T x){
		this.x = x ;
	}
	public void setY(T y){
		this.y = y ;
	}
	public T getX(){
		return this.x ;
	}
	public T getY(){
		return this.y ;
	}
};

public class GenericsPoint{
	public static void main(String args[]){
		Point<Integer> p = new Point<Integer>() ;
		p.setX(10) ;		// 利用自动装箱操作:int --> Integer
		p.setY(20) ;		// 利用自动装箱操作:int --> Integer
		int x = p.getX() ;	// 自动拆箱
		int y = p.getY() ;	// 自动拆箱
		System.out.println("整数表示,X坐标为:" + x) ;
		System.out.println("整数表示,Y坐标为:" + y) ;
	}
};

在这样程序里,减少类类型转换的操作代码,而且更加安全,如果设置的内容不是数字,则在编译的时候就会出现错误,如下所示:

class Point<T>{
	private T x ;		// 表示X坐标
	private T y ;		// 表示Y坐标
	public void setX(T x){
		this.x = x ;
	}
	public void setY(T y){
		this.y = y ;
	}
	public T getX(){
		return this.x ;
	}
	public T getY(){
		return this.y ;
	}
};

public class GenericsPoint{
	public static void main(String args[]){
		Point<Integer> p = new Point<Integer>() ;
		p.setX(10) ;		// 利用自动装箱操作:int --> Integer
		p.setY("北纬210度") ;		// 利用自动装箱操作:int --> Integer
		int x = p.getX() ;	// 自动拆箱
		int y = p.getY() ;	// 自动拆箱
		System.out.println("整数表示,X坐标为:" + x) ;
		System.out.println("整数表示,Y坐标为:" + y) ;
	}
};

泛型也可以在构造方法中使用,一般有可能使用构造方法为类中的属性赋值。

构造方法中使用泛型

构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定 而又需要通过构造设置属性内容的时候,那么构造方法的定义与之前并无不同,不需要像声明类那样指定泛型。

使用格式:

[访问权限] 构造方法 ([<泛型类型>  参数名称]){ }

例如:

class Point<T>{		// 此处可以随便写标识符号,T是type的简称
	private T var ;	// var的类型由T指定,即:由外部指定
	public Point(T var){		// 通过构造方法设置内容
		this.var = var ;
	}
	public T getVar(){	// 返回值的类型由外部决定
		return var ;
	}
	public void setVar(T var){	// 设置的类型也由外部决定
		this.var = var ;
	}
};
public class GenericsDemo08{
	public static void main(String args[]){
		Point<String> p = new Point<String>("liuxun") ;	// 里面的var类型为String类型
		System.out.println("内容:" + p.getVar()) ;
	}
};

在泛型中也可以指定多个泛型。

设置多个泛型,实例如下:

class Notepad<K,V>{		// 此处指定了两个泛型类型
	private K key ;		// 此变量的类型由外部决定
	private V value ;	// 此变量的类型由外部决定
	public K getKey(){
		return this.key ;
	}
	public V getValue(){
		return this.value ;
	}
	public void setKey(K key){
		this.key = key ;
	}
	public void setValue(V value){
		this.value = value ;
	}
};
public class GenericsDemo09{
	public static void main(String args[]){
		Notepad<String,Integer> t = null ;		// 定义两个泛型类型的对象
		t = new Notepad<String,Integer>() ;		// 里面的key为String,value为Integer
		t.setKey("刘勋") ;		// 设置第一个内容
		t.setValue(22) ;			// 设置第二个内容
		System.out.print("姓名;" + t.getKey()) ;		// 取得信息
		System.out.print(",年龄;" + t.getValue()) ;		// 取得信息

	}
};

泛型的安全警告

在泛型应用中最好在声明类对象的时候指定好其内部的数据类型,例如"Info<String>" ,但也可以不指定类型。

class Info<T>{
	private T var ;
	public T getVar(){
		return this.var ;
	}
	public void setVar(T var){
		this.var = var ;
	}
	public String toString(){		// 覆写Object类中的toString()方法
		return this.var.toString() ;
	}
};
public class GenericsDemo10{
	public static void main(String args[]){
		Info i = new Info() ;		// 警告,没有指定泛型类型
		i.setVar("MLDN") ;			// 设置字符串
		System.out.println("内容:" + i.getVar()) ;
	}
};

在Info类中并没有指定泛型的类型,则在Java中为了保证程序依然可以使用,会将T设置成Object类型,这样一来,就可以接收任何的数据类型,也就是说此时var的类型是Object,所有的泛型信息将被擦除,实际上,以上的程序就相当于以下的定义格式:

class Info<T>{
	private T var ;
	public T getVar(){
		return this.var ;
	}
	public void setVar(T var){
		this.var = var ;
	}
	public String toString(){		// 覆写Object类中的toString()方法
		return this.var.toString() ;
	}
};
public class GenericsDemo11{
	public static void main(String args[]){
		Info<Object> i = new Info<Object>() ;		// 指定Object为泛型类型
		i.setVar("MLDN") ;			// 设置字符串
		System.out.println("内容:" + i.getVar()) ;
	}
};

泛型的安全警告

在泛型应用中最好在声明类的时候指定其内部的数据类型,例如:"Info<String>",但也可以不指定类型,这样一来用户在使用这样的类的时候就会出现不安全的警告信息,如下图:

总结:

1、泛型的产生意义:为了保证数据的安全性。

2、泛型的基本使用,由外部指定的其具体操作类型。

时间: 2024-10-09 15:10:56

Java中泛型的介绍与简单使用的相关文章

Java中泛型 类型擦除

转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下面一个列子,代码如下: public class Foo { public void listMethod(List<String> stringList){ } public void listMethod(List<Integer> intList) {

Java 中 泛型的限定

泛型 一般 出现在集合中,迭代器中 也会出现! 泛型 是为了 提高代码的 安全性. 泛型 确保数据类型的唯一性. 在我们常用的容器中,  越是 单一 约好处理啊! 泛型的限定: ? 是通配符 指代 任意类型 泛型的限定上限: <? extends E> 接受 E 或者 E 的子类型. 泛型的限定下限: <?  super   E>  接收  E 或者 E 的父类. 泛型的限定上限 (定义父类 填装子类 类型!) 代码: package stu.love.v; import java

Java中泛型 使用

泛型: 1.5  之后出现  提高安全 1      泛型 确定 集合容器的类型. 2      <> 接收一种数据类型,(引用数据类型) ArrayList<String> lis = new ArrayList<String>() 目的: 将运行时期的 错误 转化到 编译时期,提高了安全性! 3      不需要 强制类型转换.  更加安全! 泛型的 擦除: 泛型在编译时期使用!使用完毕直接擦除. 编译完的时候 不存在 泛型. 好处: 使用了 泛型,不自需要强制类型

Java中的异常处理机制的简单原理和应用。

异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间.地点.人物.情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息. Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Erro

java中泛型上限,下限应用

import java.util.*; class Person implements Comparable<Person>{ String name; int age; Person(){ name = ""; age = 0; } Person(String name, int age){ this.name = name; this.age = age; } public String toString(){ return name + "...."

【转】java中Thread类方法介绍

原文: java中Thread类方法介绍 http://blog.csdn.net/seapeak007/article/details/53395609 这篇文章找时间分析一下!!!:http://blog.csdn.net/apei830/article/details/4503112 --------------------------------------------------------------- 方法摘要 static int activeCount()          

java 中 “文件” 和 “流” 的简单分析

java 中 FIle 和 流的简单分析 File类 简单File 常用方法 创建一个File 对象,检验文件是否存在,若不存在就创建,然后对File的类的这部分操作进行演示,如文件的名称.大小等 //创建一个File 对象,检验文件是否存在,若不存在就创建然后对File package wfu; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Scanner; pu

java中equals以及==的用法(简单介绍)

简单介绍 equals方法是java.lang.Object类的方法 有两种用法说明: 一.对于字符串变量来说,使用"=="和"equals()"方法比较字符串时,其比较方法不同. 1."=="比较两个变量本身的值,即两个对象在内存中的首地址. (java中,对象的首地址是它在内存中存放的起始地址,它后面的地址是用来存放它所包含的各个属性的地址,所以内存中会用多个内存块来存放对象的各个参数,而通过这个首地址就可以找到该对象,进而可以找到该对象的各

Java 中泛型的全面解析

Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JDK 5中的新集合类框架中.对于泛型概念的引入,开发社区的观点是褒贬不一.从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误.而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的