在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第二十篇博客。
本篇博客介绍了Java的泛型。
本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11。
目录
泛型
泛型概述和好处
泛型是JDK5引入的特性,提供了编译时类型安全检测机制,该机制允许在编译时检测到非法类型。泛型的本质是参数化类型,操作的数据类型被指定为一个参数。参数化类型就是将类型参数化,然后在使用的时候传入具体的类型。这种参数类型可以用在类、方法和接口中,分别称为泛型类、泛型方法和泛型接口。
泛型的定义格式是:
<类型>
指定一种类型的格式,类型可以看作形参。
<类型1,类型2...>
指定多种类型的格式,多种类型之间用逗号隔开,类型可以看作形参。
具体调用的时候给定的类型可以看成实参,实参的类型只能是引用数据类型。
泛型的好处是将运行期间的问题提前到了编译期间,避免强制类型转换。
泛型类
泛型类的定义格式是:
修饰符 class 类名<类型>{...}
类型通常用大写字母,如T表示。
public class generic1<T> {
private T thing;
public generic1(){}
public generic1(T thing){
this.thing = thing;
}
public T getthing(){
return thing;
}
public void setthing(T thing){
this.thing = thing;
}
}
generic1类是一个泛型类,其成员变量thing为T类型,private权限。并有对应的get和set方法,以及带参构造方法。
public class generictest1 {
public static void main(String[] args){
generic1<Integer> g1 = new generic1<Integer>(10);
System.out.println(g1.getthing());
generic1<String> g2 = new generic1<String>("Java");
System.out.println(g2.getthing());
generic1<Double> g3 = new generic1<Double>(7.14);
System.out.println(g3.getthing());
}
}
程序建立了三个generic1类对象,并进行了测试。注意如果是基本类型,应该用对应的基本类型包装类。程序的输出是:
10
Java
7.14
泛型方法
泛型方法的定义格式是:
修饰符 <类型> 返回值类型 方法名(类型 变量名){...}
public class generic2 {
public <T> void show(T t){
System.out.println(t);
}
}
generic2类的成员方法show方法是泛型方法,输出参数。
public class generictest2 {
public static void main(String[] args){
generic2 g1 = new generic2();
g1.show("Java");
generic2 g2 = new generic2();
g2.show(14);
generic2 g3 = new generic2();
g3.show(15.32);
}
}
程序创建了集合generic2类对象,并调用其show方法。程序的输出是:
Java
14
15.32
泛型接口
泛型接口的定义格式是:
修饰符 interface 接口名<类型>{}
public interface genericinterface<T> {
public void show(T t);
}
这是一个泛型接口,内有抽象方法show方法。
public class generic3<T> implements genericinterface<T>{
public void show(T t){
System.out.println(t);
}
}
generic3类实现了genericinterface接口,重写了show方法。
public class generictest3 {
public static void main(String[] args){
genericinterface<Integer> g1 = new generic3<Integer>();
g1.show(7);
genericinterface<String> g2 = new generic3<String>();
g2.show("Java");
genericinterface<Double> g3 = new generic3<Double>();
g3.show(15.40);
}
}
此类进行了测试,程序的输出是:
7
Java
15.4
类型通配符
为了表示各种泛型List的父类,可以使用类型通配符<?>。List<?>表示元素类型未知的List,元素可以匹配任何的类型。这种带通配符的List仅表示各种泛型List的父类,不能把元素添加到其中。
如果不希望List<?>是任何泛型List的父类,只希望代表某一类泛型List的父类,可以指定类型通配符的上限。格式是: <? extends 类型>,表示后面类型不能比这个类型高。
也可以指定类型通配符的下限,格式是<? super 类型>,表示后面类型不能比这个低。
import java.util.List;
import java.util.ArrayList;
public class genericall {
public static void main(String[] args){
List<?> list1 = new ArrayList<Integer>();
List<?> list2 = new ArrayList<String>();
List<? extends Number> list3 = new ArrayList<Integer>();
List<? extends Number> list4 = new ArrayList<Double>();
List<? super Integer> list5 = new ArrayList<Integer>();
List<? super Number> list6 = new ArrayList<Object>();
}
}
这段代码使用了类型通配符,程序无输出。
可变参数
可变参数的参数个数是可变的,用于方法的形参。格式是:
修饰符 返回值类型 方法名(数据类型...变量名){...}
这里的变量其实是一个数组,如果一个方法有多个参数,那么可变参数要放在最后。
public class variable1 {
public static void main(String[] args){
System.out.println(sum(10,20,30));
System.out.println(sum(10,20,30,40,50));
System.out.println(sum(10,20,30,40,50,60,70,80,90,100));
System.out.println(sum(495,535,164));
System.out.println(sum(923,165,478));
}
public static int sum(int...num){
int sum = 0;
for(int number:num){
sum += number;
}
return sum;
}
}
sum方法的参数是可变参数,并返回参数的和。程序的输出是:
60
150
550
1194
1566
可变参数的使用
Arrays工具类有一个静态方法,public static <T> List<T> asList(T...a) 返回指定数组支持的固定大小的列表。返回的集合不能进行增删操作,但是能进行修改操作。
List接口有一个静态方法,public static<E> List<E> of(E...elements)返回包含任意数量元素的不可变列表。返回的集合不能进行增删改操作。
Set接口有一个静态方法,public static<E> Set<E> of(E...elements)返回包含任意数量元素的不可变集合。给元素的时候不能重复。返回的集合不能做增删操作,没有修改的方法。
import java.util.Set;
import java.util.List;
import java.util.Arrays;
public class variable2 {
public static void main(String[] args){
List<String> test1 = Arrays.asList("Hello","world","and","Java");
System.out.println(test1);
List<String> test2 = List.of("Hello","world","and","Java");
System.out.println(test2);
Set<String> test3 = Set.of("Hello","world","and","Java");
System.out.println(test3);
}
}
程序的输出是:
[Hello, world, and, Java]
[Hello, world, and, Java]
[Hello, world, Java, and]