概述
泛型:参数化类型。就是将类型由原来的具体的类型变为参数化,类似于方法中的变量参数 ,然后在调用时传入具体类型
Object是Java中所有类的父类、超类、基类,位于继承树的最顶层。可以说,任何一个没有显式地继承别的父类的类,都会直接继承Object,否则就是间接地继承Object,并且任何一个类也都会享有Object提供的方法。
优点
- 提高了程序安全性
- 将运行期间遇到的问题转移到编译期
- 省去了类型强制转换的麻烦
- 泛型类的出现优化了程序设计
- 在接口、类、方法上都可以使用泛型
- 类型通配符上下限的定义
应用
- 泛型方法:List接口中的get方法
- 泛型类:ArrayLiat类
- 泛型接口:List接口
示例:泛型类与泛型类的使用
package Collection;
/**
* @ClassName : Test
* @Description : Test
* @Author : mt
* @Date: 2023-08-08 14:04
*/
//在类上定义泛型
//T/E/K/V/等形式的参数通常用于表示泛型的形参
public class Test<T> {
private T data;
public Test(){
}
//在构造方法上使用泛型-参数
public Test(T data){
this.data = data;
}
//在方法上使用泛型-返回值
public T getData(){
return this.data;
}
}
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test<String> name = new Test<String>("Tom");
System.out.println("name:"+name.getData());
Test<Integer> num = new Test<Integer>(123);
System.out.println("num:"+num.getData());
}
}
示例:泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的类型Test
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test<String> name = new Test<String>("Tom");
System.out.println("name:"+name.getData());
Test<Integer> num = new Test<Integer>(123);
System.out.println("num:"+num.getData());
System.out.println("------------------------");
//泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的类型Test
System.out.println("name class" + name.getClass());
System.out.println("num class" + num.getClass());
System.out.println("name.getClass() == num.getClass()" + (name.getClass() == num.getClass()));
}
}
示例:使用类型通配符
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test<Number> num1 = new Test<Number>(123);
Test<Integer> num2 = new Test<Integer>(456);
getData(num1);
getData(num2);
}
public static void getData(Test<Number> data){
System.out.println("data:"+data.getData());
}
}
提示问题:Number从逻辑上来讲是不能作为Test的Integer的父类
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test<String> name = new Test<String>("Tom");
Test<Number> num1 = new Test<Number>(123);
Test<Integer> num2 = new Test<Integer>(456);
getData(name);
getData(num1);
getData(num2);
}
public static void getData(Test<?> data){
System.out.println("data:"+data.getData());
}
}
示例:通配符上下限
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test<String> name = new Test<String>("Tom");
Test<Number> num1 = new Test<Number>(123);
Test<Integer> num2 = new Test<Integer>(456);
getUpperData(name);
getUpperData(num1);
getUpperData(num2);
getLowerData(name);
getLowerData(num1);
getLowerData(num2);
}
//上限限制(接受Number本身以及它的子类)
public static void getUpperData(Test<? extends Number> data){
System.out.println("data:"+data.getData());
}
//下限限制(接受Number本身以及它的父类)
public static void getLowerData(Test<? super Number> data){
System.out.println("data:"+data.getData());
}
}
示例:在方法上使用泛型
package Collection;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
Test test = new Test<>();
test.setData("Jerry");
}
}
package Collection;
/**
* @ClassName : Test
* @Description : Test
* @Author : mt
* @Date: 2023-08-08 14:04
*/
//在类上定义泛型
//T/E/K/V/等形式的参数通常用于表示泛型的形参
public class Test<T> {
//将泛型定义在方法上,泛型必须放到返回值的前面、修饰符的后面
public <E> void setData(E e){
System.out.println(e.toString());
}
}
示例:在接口上使用泛型
package Collection;
import Collection.service.impl.InterImpl01;
import Collection.service.impl.InterImpl02;
/**
* @ClassName : GenericTest
* @Description : GenericTest
* @Author : mt
* @Date: 2023-08-08 14:09
*/
public class GenericTest {
public static void main(String[] args) {
InterImpl01 impl01 = new InterImpl01();
impl01.show("abc");
InterImpl02<Integer> impl02 = new InterImpl02();
impl02.show(5);
}
}
package Collection.service.impl;
import Collection.service.Inter;
/**
* @ClassName : InterImpl01
* @Description : InterImpl01
* @Author : mt
* @Date: 2023-08-08 16:33
*/
public class InterImpl01 implements Inter<String>{
public void show(String str){
System.out.println("show"+str);
}
}
package Collection.service.impl;
import Collection.service.Inter;
/**
* @ClassName : InterImpl02
* @Description : InterImpl02
* @Author : mt
* @Date: 2023-08-08 16:42
*/
public class InterImpl02<W> implements Inter<W> {
public void show(W q){
System.out.println("show"+q);
}
}
package Collection.service;
/**
* @ClassName : Inter
* @Description : Inter
* @Author : mt
* @Date: 2023-08-08 16:29
*/
public interface Inter<T> {
public void show(T t);
}