泛型
1.1、泛型的定义
泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型的就可以在使用时决定了。
1.2、泛型的使用方式
泛型有三种使用方式,分别泛型类、泛型接口、泛型方法
。
1.2.1、泛型类:
把泛型定义在类上。语法格式
public class 类名 <泛型类型1,....> {
}
package com.lyc.lesson;
class Person<T>{
private T t;
public Person(T t) {
this.t = t;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
public class Lesson03 {
public static void main(String[] args) {
Person<String> person = new Person<String>("这是一个测试");
System.out.println(person.getT());
//在尖括号中要写入包装类。
Person<Integer> person1 = new Person<>(123);
System.out.println(person1.getT());
}
}
关于泛型类中的成员方法问题:
package com.lyc.lesson;
//泛型类
class Student<T>{
//泛型方法
public <T> void study(T t){
System.out.println(t);
}
}
public class Lesson02 {
public static void main(String[] args) {
Student<String> student = new Student<>();
student.study(3);
}
}
根据上述案例提问,泛型类中泛型方法上是否与泛型类上的有关系?
答:没有关系。
分析:我们通过创建对象对Student类的泛型做出规定为String类型。按照正常思路来讲,Student为String类型,那么,我们类里面的这个成员方法的参数类型也行该是Stirng类型。但是当我们调用这个成员方法时发现,这个study方法所需要的参数类型不是String类型而是Object类型(图1)。故,泛型类中成员方法上与泛型类上的没有关系。
那么,如何保持类的数据类型和成员方法的参数的数据类型保持一致。
不要在成员方法上加。当我们不在方法上加之后,成员方法的参数类型就和泛型类的数据类型保持了一致
package com.lyc.lesson;
class Student<T>{
public void study(T t){
System.out.println(t);
}
}
public class Lesson02 {
public static void main(String[] args) {
Student<String> student = new Student<>();
student.study("张三");
}
}
泛型抽象类:
把泛型定义在抽象类上。语法格式
abstract class 类名 <T> {
}
在继承抽象类时,抽象类的子类也要使用泛型。
1.2.2、泛型接口:
把泛型定义在接口上。语法格式:
public interface 接口名 <泛型类型1,...>{
}
package com.lyc.lesson;
interface Person1 <T> {
void show(T t);
}
class Test<T> implements Person1<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
class Test2<T> implements Person1<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
public class Lesson04 {
public static void main(String[] args) {
Test test = new Test();
test.show("这是一个泛型接口测试");
Test2 test2 = new Test2();
test2.show(123);
}
}
注意事项:
在泛型接口中,去实现该接口的类也必须带有泛型,否则子类是无法使用父类的泛型的。同时还要保证实现类的泛型和接口的泛型一致,否则会报错,如下图所示:
1.2.3、泛型方法:
泛型方法,是在调用方法的时候指明泛型的具体类型。语法格式
修饰符 <代表泛型的变量> 返回值类型 方法名 (参数){
}
package com.lyc.lesson;
public class Lesson05 {
public static void main(String[] args) {
test("有参无返回值的方法测试");
test1("有参有返回值的方法测试");
test2();
test3();
}
//有参无返回值 有必要使用泛型
public static <T> void test(T t){
System.out.println(t);
}
//有参有返回值 有必要使用泛型
public static <T> T test1(T t){
System.out.println(t);
return t;
}
//无参无返回值
public static <T> void test2(){
System.out.println("无参无返回值的方法测试");
}
//无参有返回值
public static <T> T test3(){
System.out.println("无参有返回值的测试方法");
return null;
}
}
注意事项:
1、public 与 返回值中间非常重要,可以理解为声明此方法为泛型方法。
2、只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
3、表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
4、与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E等形式的参数常用于表示泛型。