泛型的介绍
(1) 泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题
(2)在类声明或实例化时只要指定好需要的具体的类型即可。
(3)Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮
(4)泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
下面有个具体的例子:
public class Generic01 {
public static void main(String[] args) {
//注意,特别强调: E 具体的数据类型在定义 Person 对象的时候指定,
// 即在编译期间,就确定 E 是什么类型
Person<String> person1 = new Person<>("txl");
Person<Integer> person2 = new Person<>(120);
person1.showClass();
person2.showClass();
}
}
class Person<E>{
E s;
public Person(E s) {
this.s = s;
}
public void showClass(){
System.out.println(s.getClass());
}
}
(5)在给泛型指定具体的类型后,可以传入该类型或者该类型的子类型
比如String是Object的子类
ArrayList<Object> arrayList = new ArrayList<>();
arrayList.add("txl");
自定义泛型
自定义泛型类:
结构如下所示:
class 类名<T,R…>{
成员
}
在自定义泛型类中其中有一些使用细节:
1.普通的属性,方法可以使用泛型
2.使用泛型的数组不可以初始化,因为不知道开辟多大的空间,如果使用,编译器会报错。
3.静态方法,静态属性不可以使用泛型,因为静态方法,静态属性在类加载时就初始化了,此时还没有创建对象,类型还未确定,会出现错误。
自定义泛型接口:
interface 接口名<T,R…>{
}
在自定义接口中有一些使用细节:
1.在接口中,静态属性不能使用泛型(注意:接口中所有的属性都是静态属性)
2.自定义泛型接口在继承接口或者实现接口时确定泛型。
3.如果没有指定泛型,那么就是Object
自定义泛型方法:
class Car<E,T>{
public void run(E e){
}//使用类声明的泛型的方法,不是泛型方法
public <R> void fly(R r){
}//这个才是泛型方法
}
使用的一些细节:
1.泛型方法可以定义在普通类中,还可以定义在泛型类中
2.当泛型方法被调用时,传入参数的类型会确定泛型
泛型的继承与通配符
1.泛型不具有继承性
List<Object> list = new ArrayList<String>();
//这种写法是错误的
2.泛型的一些通配符
<?>:支持任意类型的泛型
<? extends A>支持A类以及A类的子类,确定了泛型的上限
<? super A>支持A类以及A类的父类,但不限于直接父类,确定了泛型的下限
JUNIT5.4
一段代码有很多功能需要测试,通常我们会将它们放在main方法中,这样比较麻烦,但是如果我们使用了JUNIT,可以直接运行一个方法,并给出信息,很方便。
JUnit是Java语言的一个单元测试框架。
import org.junit.jupiter.api.Test;
@Test
public void m1(){
System.out.println("hello,world!");
}