设为首页 加入收藏

TOP

泛型的定义、用法与类型通配符的使用方式(一)
2019-09-17 18:52:41 】 浏览:58
Tags:定义 用法 类型 通配符 使用 方式

泛型是什么?

泛型本质是指类型参数化。意思是允许在定义类、接口、方法时使用类型形参,当使用时指定具体类型,所有使用该泛型参数的地方都被统一化,保证类型一致。如果未指定具体类型,默认是Object类型。集合体系中的所有类都增加了泛型,泛型也主要用在集合。
 

泛型的定义

泛型类:public class Demo<T> {} ,T表示未知类型。
泛型接口:public interface ImplDemo<T,V>{} ,和定义类一样(接口就是一个特殊类)。
泛型方法:public <T>  void demo1(T name){System.out.println(name);} , public <T> T demo2(T t){ return t;}
 

泛型的好处

  1. 编译时确定类型,保证类型安全,避免类型转换异常。
  2. 避免了强制类型转换。
  3. 代码利于重用,增加通用性。

泛型的限制和规则

  • 泛型的类型参数只能是引用类型,不能使用值类型。
  • 泛型的类型参数可以有多个。
  • 泛型类不是真正存在的类,不能使用instanceof运算符。
  • 泛型类的类型参数不能用在静态申明。
  • 如果定义了泛型,不指定具体类型,泛型默认指定为Ojbect类型。
  • 泛型使用?作为类型通配符,表示未知类型,可以匹配任何类型。因为是未知,所以无法添加元素。
  • 类型通配符上限:<? extends T>,?代表是T类型本身或者是T的子类型。常用于泛型方法,避免类型转换。
  • 类型通配符下限。<? super T>,?代表T类型本身或者是T的父类型。
  • 除了通配符可以实现限制,类、接口和方法中定义的泛型参数也能限制上限和下限。
 

泛型代码实例

接下来,使用代码来演示泛型的用途,建议使用目录查看具体内容。
 

集合类演示泛型

		//未指定泛型
		TreeSet ts = new TreeSet();
		ts.add(10);
		ts.add(25);
		ts.add("30");
		System.out.println(ts);//运行时报错,类型转换异常
		
		//mode 2
		TreeSet<Integer> ts2 = new TreeSet<>();
		ts2.add(10);
		ts2.add(25);
		ts2.add("30"); //编译器提示报错,无法添加非Integer类型
	

未使用泛型时,可以添加任意元素,因为TreeSet会比较每一个元素,所以运行时会引发类型转换异常。使用泛型后,只能添加同一个类型,所以不会出错。

 

定义泛型类

public class Person<T> {
	private T name;//类型是未知的
	
	public Person(T name) {
		this.name = name;
	}	
	
	public T getName() {
		return name;
	}
	
	public void sexName(T name) {
		this.name = name;
	}

}
在上面实例中,Person类定义成泛型类,成员变量name的类型指定为T,表示未知类型。实例化该类对象后,可以看到name的类型是Object,表示可以接收任何类型。
		Person p = new Person(10);	//new Person(Object name)
加上泛型后
		//使用泛型两种方式
		Person<String> ps = new Person<String>(); //new Person<String>(String name)
		Person<String> ps = new Person<>();//new Person<>(T name)
第一种,会直接确定参数类型是什么,而第二种的参数类型是T ,但如果加入的非String类型,编译器会检查并报错。两者区别不大。在JDK1.7之后使用第二种,会自动检查泛型,可以省略后部分<>的泛型参数,建议使用第二种。


定义泛型接口

interface A<T>{
	void display(T value); 
	T getValue(T v);
}

//未对泛型接口指定具体类型
public class Person implements A{

	@Override
	public void display(Object obj) {
		System.out.println();
	}

	@Override
	public Object getValue(Object v) {
		return null;
	}
	
}
如果我们定义了泛型,不指定具体类型,默认就是Object类型。当我们为泛型接口指定具体类型后,代码如下:

 

//泛型接口
interface A<T>{
	void display(T value); 
	T getValue(T v);
}

//为泛型接口指定具体类型
public class Person implements A<String>{
	@Override
	public void display(String value) {
	}
	@Override
	public String getValue(String v) {
		return null;
	}
}
泛型接口指定具体类型后,所有使用了该泛型参数的地方都被统一化。其实泛型接口和泛型类是一样的写法。

 

定义泛型方法

先使用常规方法进行对比。

	public static void main(String[] args) {
		int[] arr = new int[] {1, 8, 15, 6, 3};
		double[] douArr = {10.5, 25.1, 4.9, 1.8};
		String[] strArr = {"我","是","字","符","串"};
		forArr(strArr);
		
	}
	
//遍历数组的重载方法,支持int和double类型	
	public static void forArr(int[] arr) {
		for(int i=0; i<arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
	//重载了
	public static void forArr(double[] arr) {
		for(double d : arr) {
			System.out.println(d);
		}
	}
	//……
	//……

 

如上所示,如果想遍历Stirng类型数
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇上云之路之企业级云上网络解决方案 下一篇如何拆分微服务架构?

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目