Java面向对象系列[v1.0.0][泛型基础]

Java5增加泛型支持,很大程度上是为了让集合记住其元素的数据类型,在此之前不用泛型的话,一旦把一个对象放进Java集合中,集合就会忘记对象的类型,把所有的对象当成Object类型处理,从集合里取出对象后,还需要进行强制类型转换
增加了泛型支持后的集合,完全可以记住集合中元素的类型,并且在编译时检查集合中元素的类型,如果试图向集合中添加不满足类型要求的对象,编译器就会提示错误,增加泛型的集合让代码更简洁更健壮

泛型基础

import static java.lang.System.*;

public class ListErr
{
	public static void main(String[] args)
	{
		// 创建一个只想保存字符串的List集合
		List strList = new ArrayList();
		strList.add("两岸猿声啼不住");
		strList.add("轻舟已过万重山");
		strList.add(5);
		// 引发ClassCastException异常,程序试图将Integer对象转换为String类型
		strList.forEach(str -> out.println(((String)str).length()));
	}
}

在Java5之后,引入了“参数化类型(parameterized type)”,它被称之为泛型(Generic)

import static java.lang.System.*;
public class GenericList
{
	public static void main(String[] args)
	{
		//创建一个只想保存字符串的List集合
		List<String> strList = new ArrayList<String>();
		strList.add("古道西风瘦马");
		strList.add("断肠人在天涯");
		strList.add(5);
		strList.forEach(str ->out.println(strList.length()));
	}
}

在集合接口、类后增加尖括号,尖括号里放一个数据类型,表明该集合接口、集合类只能保存这个数据类型的对象

  • List:该List是带一个类型参数的泛型接口,类型参数是String
  • ArrayList():创建这个ArrayList对象时也指定了类型参数
  • 也因此最后的out.println里已经不需要进行强制类型转换,因为strList已经记住了该集合里对象的类型是String类型

菱形语法

在Java7之前,如果使用带泛型的接口、类定义变量,那么调用构造器创建对象时构造器的后面也必须带泛型,例如:

List<String> strList = new ArrayList<String>();
Map<String, Integer> score = new HashMap<String, Integer>();

从Java7开始,Java允许在构造器后不要带完整的泛型信息,只要给出一堆尖括号即可

List<String> strList = new ArrayList<>();
Map<String, Integer> score = new HashMap<>();

两个尖括号里什么都不放,并排挨着放一起非常像一个菱形,这种语法也就被称为菱形语法,实际上对原有的泛型并没有改变,只是更好的进行了简化

import java.util.*;
import static java.lang.System.*;

public class DiamondTest
{
	public static void main(String[] args)
	{
		// Java自动推断出ArrayList的<>里应该是String
		List<String> books = new ArrayList<>();
		books.add("铁道旁赤脚追晚霞");
		books.add("玻璃珠铁壳英雄卡");
		// 遍历books集合,集合元素就是String类型
		books.forEach(ele -> out.println(ele.length()));
		// Java自动推断出HashMap的<>里应该是String, List<String>
		Map<String, List<String>> schoolsInfo = new HashMap<>();
		// Java自动推断出ArrayList的<>里应该是String
		List<String> schools = new ArrayList<>();
		schools.add("这是个旅途");
		schools.add("一个叫做命运的慢慢旅途");
		schoolsInfo.put("炊烟袅袅升起", schools);
		// 遍历Map时,Map的key是String类型,value是List<String>类型
		schoolsInfo.forEach((key, value) -> out.println(key + "-->" + value));
	}
}

import static java.lang.System.*;

// 定义一个带泛型声明的接口
interface Foo<T>
{
	void test(T t);
}
public class AnnoymousDiamond
{
	public static void main(String[] args)
	{
		// 指定Foo类中泛型为String
		Foo<String> f = new Foo<>()
		{
			// test()方法的参数类型为String
			public void test(String t)
			{
				out.println("test方法的t参数为:" + t);
			}
		};
		// 使用泛型通配符,此时相当于通配符的上限为Object
		Foo<?> fo = new Foo<>()
		{
			// test()方法的参数类型为Object
			public void test(Object t)
			{
				out.println("test方法的Object参数为:" + t);
			}
		};
		// 使用泛型通配符,此处写法表示通配符的上限为Number
		Foo<? extends Number> fn = new Foo<>()
		{
			// 此时test()方法的参数类型为Number
			public void test(Number t)
			{
				out.println("test方法的Number参数为:" + t);
			}
		};
	}
}

发布了207 篇原创文章 · 获赞 124 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dawei_yang000000/article/details/105275145
今日推荐