Java基础18--泛型--工具类--JDK1.5新特性

本文介绍了Java中的泛型技术,包括泛型的概述、擦除与补偿、在集合中的应用、泛型类、泛型方法、泛型接口及其上下界。还探讨了JDK1.5引入的新特性,如静态导入、可变参数、forEach循环等,并提供了相关示例。通过对泛型和新特性的理解,有助于提升Java编程的效率和安全性。
摘要由CSDN通过智能技术生成

18-1,泛型-概述

1,泛型是JDK1.5出现的新技术,新技术的出现是为了解决问题。

2,泛型可以用于明确一个集合中存储什么类型的元素

ArrayList<String> al = new ArrayList<String>();
al.add("abc");//正确
//al.add(3);//编译直接报错
//在迭代器上加上泛型,下面取出来的时候就不用强转了
Iterator<String> it = al.iterator();
while(it.hasNext()) {
	//在这里不用强转了,因为从it中取出的肯定是String
	String str = it.next();
	System.out.println(str);
}

3,好处

(1)将运行时间的问题ClassCastException转到了编译时期。

(2)避免了强制转换的麻烦。

4,泛型什么时候用呢?

当操作的引用数据类型不确定的时候,就用泛型,将要操作的引用数据类型写在<>中即可。其实<>就是一个用于接收具体引用数据类型的参数范围。

在程序中,只要用到了带有<>的类型或者接口,就要明确传入的具体引用数据类型。

也可以同时接受多个数据类型:

class Tool<e1,e2,e3,e4>
Tool<String,Demo,Person,Integer> t = new Tool<String,Demo,Person,Integer>();

18-2,泛型-擦除&补偿

1,泛型解决了编译时期的安全问题,是给编译器使用的技术。

2,运行时,会将泛型去掉,生成的class文件中是不带有泛型的,这个称为泛型的擦除。

为什么要擦除呢?

因为为了兼容运行时的类加载器,因为泛型是JDK1.5的新特性,如果class文件中加上泛型的话,类加载器会不认识,若想要类加载器认识泛型,类加载器也要升级,为了避免升级类加载器的麻烦,泛型将交由编译器处理,编译通过后就会把他删去,使之前的类加载器也能运行它。

3,泛型的补偿:

擦除后,如果对元素进行取出的赋值动作,如:String str =it.next();是否需要加上强转呢?答案是不用了,首先,加上泛型且编译通过就能保证集合中的数据是指定的类型了,所以认为不会出现规定类型以外的元素。其实,在运行时,是自动添加了一步动作,通过用getClass()方法获取元素的类型再对其进行一次转换动作,就不用使用者在强制转换了。

 

18-3,泛型-在集合中的应用

1,以TreeSet为例,TreeSet具备比较功能,但存入的类型必须实现Comparable接口并实现了里面的compareTo方法才可以;或者定义一个比较器,实现Comparator接口并实现里面的compare方法也可以。定义TreeSet时,如果不加泛型Eclipse等IDE会有黄色波浪线提示,加上泛型,黄色波浪线即可消失。

2,上一章提到的Person类实现Comparable接口时Comparable接口也需要指定泛型,如:Comparable<Person>,指定后,覆写的compareTo方法中的参数就可以不写Object了,直接写Person就可以,方法体中的代码也不用强制向下转型了。Comparator接口也要加上泛型,它里面的compare方法的两个参数也直接接受Person类型就可以了。例如:

class Person implements Comparable<Person> {
	...code...
	public int compareTo(Person p) {
		//Person p = (Person)p;//强转可以省去,因为定义了泛型
		int temp = this.age = p.age;
		return temp == 0 ? this.name.compareTo(p.name) : temp;
	}
	...code...
}

18-4,泛型类

1,以前定义工具类的时候这么定义:

public class Tool {
	private Object object;
	public Object getObject() {
		return object;
	}
	public void setObject(Object object) {
		this.object = object;
	}
}

别的类用这个工具类的时候,可以这样做:

Tool tool = new Tool();
/*
这里因为没有Worker这个类,所以是错误的。
Worker为传入的错误值,但编译不会报错,因为Tool中接收的是Object类型,
下面的语句必须做强转才能匹配类型,因为把Worker向上提升为了Object。
*/
tool.setObject(new Worker());
Student stu = (Student)tool.getObject();

工具类是针对所有类型的,而任何一个类都是Object的子类,所以根据多态的特性,通过将参数定义成Object我们就可以使这个方法接收所有类型的参数,在没有泛型的时候我们就只能这么做。

在JDK1.5之后,使用泛型来接收类中要操作的引用数据类型,这就是泛型类。

泛型类什么时候用呢?

当类中的操作的引用数据类型不确定的时候,就是用泛型来表示。

例如:

public class Tool<Q> {
	private  Q q;
	public Q getObect() {
		return q;
	}
	public void setObject(Q object) {
		this.q = object;
	}
}

有泛型后,在别的类用到工具类的时候,可以这么做:

Tool<Student> tool = new Tool<Student>();
//tool.setObject(new Worker());//编译报错,因为有了泛型指定的Student,所以别的不能进入集合。
tool.setObject(new Student());
Student stu = tool.getObject();

 

18-5,泛型方法

1,在18-4中有泛型的Tool类中加入泛型方法,Tool<QQ>

public class Tool<Q> {
	private  Q q;
	public Q getObect() {
		return q;
	}
	public void setObject(Q object) {
		this.q = object;
	}
	/*
	如果方法不加泛型会报错,因为Tool明确只能接收QQ类型,
	所以不能操作W类型,要想让其中一个方法操作W类型,
	必须在返回值类型前加上泛型<W>。
	*/
	public <W> void show(W str) {
		System.out.println("show" + str.toString());
	}
	/*
	另外,print接收的是字符串,那么能不能打印字符串的长度呢?
	答案是不能的,因为QQ str = &#
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值