Java泛型使用示例整理

Java泛型使用示例整理

目标

Java泛型编程是JDK1.5版本后引入的。泛型让编程人员能够使用类型抽象,通常用于集合里面。本文旨在整理一些泛型的用法。

用法

泛型分两部分。一部分是泛型类和方法的定义。另一部分是泛型类和方法的使用。

定义篇

类定义时,使用泛型

在定义类的时候,我们可以使用泛型。如下代码:

class Demo  {
	T field;
	
	public void setFiled(T field) {
		this.field = field;
	}
	
	public T getField() {
		return field;
	}
}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Demo demo = new Demo();
		demo.setFiled("www.bo56.com");
		System.out.println(demo.getField());
	}
}

类名后面增加 ,说明是泛型类。T可以视为类型的占位符。泛型类的代码就可以使用这个占位符T。

无参数方法定义时,使用泛型

无论在泛型类,还是普通类中,我们都可以再方法中使用泛型。

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

class Demo {
	
	public  List newArrayList() {
		return new ArrayList();
	}
}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Demo demo = new Demo();
		List list = demo.newArrayList();
		list.add("www.bo56.com");
		list.add("bo56.com");
		//list.add(1); 报错。只能添加String
		for (String str:list) {
			System.out.println(str);
		}
	}
}

方法的返回值前面,修饰符后面增加

,表示为泛型方法。这样,就可以在方法的代码中使用T代表类型。

没有参数的泛型方法,类型的确定,是根据等号左边的类型推导泛型的最终类型。

有参数方法定义时,使用泛型

class Demo {
	
	public  void showClass(T t) {
		System.out.println(t.getClass());
	}
}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Demo demo = new Demo();
		demo.showClass("123");
		demo.showClass(123);
	}
}

有参数的泛型方法,类型的确定,是根据参数类型自动推导。

方法定义时,使用通配符 ?

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

class Demo {
	
	public void show(List list) {
		list.add(null);
		//list.add(123); 编译错误
		for (Object object:list) {
			System.out.println(object);
		}
	}
}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Demo demo = new Demo();
		List listStr = new ArrayList();
		listStr.add("abc");
		demo.show(listStr);
		List listLong = new ArrayList();
		listLong.add(123L);
		demo.show(listLong);
	}
}

1、只能往集合中add null。

2、因为集合中的类型不确定。因此,为了安全,转换为Object。

类或者方法定义时,使用通配符

class Demo {
	
	public  void showClass(T t) {
		System.out.println(t.getClass());
	}
}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Demo demo = new Demo();
		demo.showClass(123);
		demo.showClass(123f);
		demo.showClass(123L);
		// demo.showClass("123"); 有错误 参数的类型,只能是 Number类型或者其子类
	}
}

表示传入的类型必须是Number或者其子类型。

使用篇

指定固定的类型

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

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List list = new ArrayList();
		//List listN = new ArrayList(); 编译错误。List 并不是 ArrayList 的父类。
	}
}

如果变量声明时,为泛型指定的类型为固定类型。如List
,就是为泛型指定的类型为Long。那么后续在给变量赋值时,指定的变量也得为这个类型。如 ArrayList

(),指定的也是Long。

对于泛型来说,Long是Number的子类。但是,List
并不是List 的子类。

使用通配符 ?

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

class Food {}

class Fruit extends Food {}

class Apple extends Fruit {}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List list = new ArrayList();
		//list.add(new Food()); 编译错误
		//list.add(new Fruit()); 编译错误
		//list.add(new Apple()); 编译错误
		list.add(null);
		//Food food = list.get(0);
		//Fruit fruit = list.get(0);
		//Apple apple = list.get(0);
		Object object = list.get(0);
	}
}

1、只能添加null。

2、获取的值只能赋值给Object类型。

因为通配符?表示该集合存储的元素类型未知,可以是任何类型。往集合中加入元素需要是一个未知元素类型的子类型,正因为该集合存储的元素类型未知,所以我们没法向该集合中添加任何元素。唯一的例外是null,因为null是所有类型的子类型,所以尽管元素类型不知道,但是null一定是它的子类型。

使用上界通配符

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

class Food {}

class Fruit extends Food {}

class Apple extends Fruit {}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List list = new ArrayList();
		// List listA = new ArrayList(); 编译错误。不能为父类。
		List listN = new ArrayList();
		listN.add(null);
		//listN.add(123); 不能add
		Fruit fruit = listN.get(0);
		Food food = listN.get(0);
		//Apple apple = listN.get(0); 编译错误。get获取的值,只能给父类
		listN.remove(0);
	}
}

上界通配符,一般用于读取的场景。

1、为泛型指定的类型只能是Fruit类型或者其子类。

2、只能为其列表添加null。

3、get方法获取的值只能赋值给Fruit类或者其超类。

使用下界通配符

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

class Food {}

class Fruit extends Food {}

class Apple extends Fruit {}

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List list = new ArrayList();
		List listA = new ArrayList(); 
		//List listN = new ArrayList(); 编译错误,不能为子类
		listA.add(new Fruit());
		//listA.add(new Food()); 编译错误,不能为父类。
		listA.add(new Apple());
		Object object = listA.get(0);
		//Fruit fruit = listA.get(0);编译错误。
		//Food food = listA.get(0);编译错误。
		//Apple apple = listA.get(0); 编译错误。
	}
}

下界通配符,一般用于写入的场景。

1、为泛型指定的类型必须为Fruit,或者其超类。

2、可以为其列表添加任意Fruit类型,或者其子类。

3、get方法获取的类型,只能赋值给Object类型。

边界通配符总结

边界通配符总结

如果你想从一个数据类型里获取数据,使用 ? extends 通配符

如果你想把对象写入一个数据结构里,使用 ? super 通配符

如果你既想存,又想取,那就别用通配符。

注意

泛型类型是被所有调用共享的

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

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Listl1 = new ArrayList();  
		Listl2 = new ArrayList();  
		System.out.println(l1.getClass() == l2.getClass()); //True  
	}
}

所有泛型类的实例都共享同一个运行时类,类型参数信息会在编译时被擦除。因此考虑如下代码,虽然ArrayList
和ArrayList 类型参数不同,但是他们都共享ArrayList类,所以结果会是true。

instanceof

import java.util.ArrayList;
import java.util.Collection;

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		Collection cs = new ArrayList();  
		if (cs instanceof Collection){}// compile error.如果改成instanceof Collection则不会出错。  
	}
}

不能对确切的泛型类型使用instanceOf操作。如下面的操作是非法的,编译时会出错。

泛型数组问题

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

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List[] lsa = new ArrayList[10]; //compile error.
	}
}

不能创建一个确切泛型类型的数组。

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

public class Test {
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List[] lsa = new ArrayList[10]; // ok, array of unbounded wildcard type  
	}
}

能创建带通配符的泛型数组.

参考

http://qiemengdao.iteye.com/blog/1525624

http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html

原文链接:Java泛型使用示例整理,转载请注明来源!

稿源:博学无忧 (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 后端存储 » Java泛型使用示例整理

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录

登录

忘记密码 ?

切换登录

注册