一、自定义泛型类
1.基本语法
class 类名 <T,R…>{
成员
}
<T,R…>表示可以有多个泛型
2.使用细节
- 普通成员可以使用泛型(属性、方法),但不能是静态的
- 使用泛型的数组,不能初始化
- 静态方法中不能使用类的泛型
- 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型),不能是基本数据类型
- 如果在创建对象时,没有指定类型,默认为Object
细节解析
class demo<T,R,M>{
//细节一
T a;
R b;
M c;
// static T d; //错误,因为泛型不能为静态
//返回值类型,也可以是泛型
public T getA() {
return a;
}
//方法中使用到泛型
public void setA(T a) {
this.a = a;
}
//细节二
//错误的,因为数组在new时不能确定T的类型,就无法在内存开空间
// T[] ar = new T[10];
//细节三
//如果静态方法或静态属性使用了泛型,JVM就无法完成初始化
// static public void A(T a){ //错误,因为方法不能为静态
//
// }
//细节四和细节五前面提到过
}
二、自定义泛型接口
1.基本语法
interface 接口名 <T,R…>{
}
2.使用细节
- 接口中,静态成员也不能使用泛型
- 泛型接口的类型,在继承接口或者实现接口时确定,若没有指定泛型类型,默认为Object
class test1{
@SuppressWarnings({"all"})
public static void main(String[] args){
}
}
interface demo<T,R>{
//细节一:接口中,静态成员也不能使用泛型
int a = 10; //ok的
// T b = 10; //错误,因为接口中变量默认是static
T A(R a); //返回类型为T,参数为R的抽象方法
void B(R b);
void C(T c,R c2);
}
//细节二
interface demo1 extends demo<String,Double>{};
class A1 implements demo1{
@Override
public String A(Double a) {
return null;
}
@Override
public void B(Double b) {
}
@Override
public void C(String c, Double c2) {
}
}
class A2 implements demo<String ,Integer>{
@Override
public String A(Integer a) {
return null;
}
@Override
public void B(Integer b) {
}
@Override
public void C(String c, Integer c2) {
}
}
//如果没有指定泛型,默认是Object
class A3 implements demo{
@Override
public Object A(Object a) {
return null;
}
@Override
public void B(Object b) {
}
@Override
public void C(Object c, Object c2) {
}
}
三、自定义泛型方法
1.基本语法
访问修饰符 <T,R…> 返回类型 方法名(参数列表){
}
2.使用细节
- 泛型方法,可以定义在普通类中,也可以定义在泛型类中
- 当泛型方法被调用时,来确定泛型的类型
- public void test(E e){},修饰符后没有<T,R…>,说明test不是泛型方法,而是使用了泛型而已
- 泛型方法,在使用类声明泛型的同时,也可以使用自己声明的泛型
class test1{
@SuppressWarnings({"all"})
public static void main(String[] args){
//细节二
demo demo = new demo();
demo.B("张三",18);
}
}
//细节一
class demo{ //普通类
public void A(){}; //普通方法
//<T,R>就是泛型,提供B使用的
public <T,R> void B(T t,R r){ //泛型方法
System.out.println(t.getClass());
System.out.println(r.getClass());
}
}
class demo1<T,R>{
public void A(){}; //普通方法
public <T,R> void B(T t,R r){} //泛型方法
}
//细节三
class demo2<T,R>{
//该方法不是泛型方法,而是使用了类中泛型的参数
public void B(T t,R r){}
}
//细节四
class demo3<T,R>{
public <M> void B(T t,M m){} //t是类的泛型,m是方法的泛型
}
四、泛型的继承和通配符☆
- 泛型不具备继承性 比如:List< Object > list = new ArrayList< String >(); //错误的
- <?>:表示支持任意泛型类型
- <? extends A>:支持A类以及A类的子类,规定了泛型的上限
- <? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
源码中有很多以上的泛型表示
import java.util.ArrayList;
import java.util.List;
class test1{
@SuppressWarnings({"all"})
public static void main(String[] args){
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<A> list3 = new ArrayList<>();
List<B> list4 = new ArrayList<>();
List<C> list5 = new ArrayList<>();
//List<?>
printCollection1(list1); //正确
printCollection1(list2); //正确
printCollection1(list3); //正确
printCollection1(list4); //正确
printCollection1(list5); //正确
//<? extends A>
// printCollection2(list1); //错误
// printCollection2(list2); //错误
printCollection2(list3); //正确
printCollection2(list4); //正确
printCollection2(list5); //正确
//<? super A>
printCollection3(list1); //正确
// printCollection3(list2); //错误
printCollection3(list3); //正确
// printCollection3(list4); //错误
// printCollection3(list5); //错误
}
//说明: List<?> 表示 任意的泛型类型都可以接受
public static void printCollection1(List<?> c) {
for (Object object : c) { // 通配符,取出时,就是 Object
System.out.println(object);
}
}
//<? extends A>:可以接受 A 或者 A 子类
public static void printCollection2(List<? extends A> c) {
for (Object object : c) { // 通配符,取出时,就是 Object
System.out.println(object);
}
}
//<? super A>:支持 A 类以及 A 类的父类
public static void printCollection3(List<? super A> c) {
for (Object object : c) { // 通配符,取出时,就是 Object
System.out.println(object);
}
}
}
class A{}
class B extends A{}
class C extends B{}
五、JUnit简单介绍
引入:
一个类有很多功能代码需要测试,为了测试,就需要写入到main方法中,如果有多个功能代码测试,就需要来回注销,切换很麻烦。如果可以直接运行某一个方法,就方便很多
基本介绍
JUnit是一个Java语言的单元测试框架,多数Java的开发环境都已经集成了JUnit作为单元测试的工具类