1.简介
泛型就是参数化类型,将一个数据类型作为参数
在定义时不知道用什么类型,在使用时指定具体的类型,类似于参数,称为参数化类型
分类:
- 泛型类
- 泛型接口
- 泛型方法
2.泛型类
- 表示类中有一个未知的类型
- 定义方法 : public class 类名{ },T表示一种数据类型,是泛型的类型参数,可以使用任意标识 一般 使用 T K V E
- 可以在类中使用T,表示一个类型
- 在使用类时需要在类名后通过<类型>指定具体类型,就是将T表示的类型传入
类名<类型> 对象名 = new 类名<>(); - 泛型只能传入引用类型,如果是基本类型,就使用包装类
package javaSE12_泛型;
import java.util.ArrayList;
public class Test01_泛型类 {
public static void main(String[] args) {
/*A a = new A();
a.array = new Integer[5];
a.array = new String[5];*/
//类名<类型> 对象名 = new 类名<>();
// 在使用时传入具体的类型,不能转入基本类型
B<Integer> b = new B<>();
b.array = new Integer[5];
// b.array = new String[5];
}
}
// 普通类
class A{
// 在没有泛型前,是通过Object来实现。Object类型安全性低。java引入了泛型
Object[] array;
}
// 泛型类 public class 类名<T>{ }
class B<T>{//T 表示一种未知的类型
T[] array;// 在定义时不知道用什么类型,在具体使用的时候 才明确类型
T a;
public void test(int a,T b){
}
}
3.泛型接口
- 表示接口中有一个未知的类型
- 定义方法 : public interface 接口名{ }
- 可以在接口中使用T,表示一个类型
- 在使用类时需要在接口名后通过<类型>指定具体类型,就是将T表示的类型传入
package javaSE12_泛型;
public class Test02_泛型接口 {
public static void main(String[] args) {
Student s1 = new Student(12, "tom");
Student s2 = new Student(15, "jack");
s1.compare(s2);
Dog d1 = new Dog("傻狗",2);
Dog d2 = new Dog("疯狗",4);
d1.compare(d2);
}
}
/**
* 提供了一个比较的方法
* @author wenwen
*
*/
interface CompareIntf<T>{
void compare(T t);
}
class Student implements CompareIntf<Student>{
private int age;
private String name;
/**
* 比较两个学生
*/
@Override
public void compare(Student s) {
if(this.age > s.getAge()){
System.out.println(this.name+"比较大");
}else{
System.out.println(s.getName()+"比较大");
}
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Dog implements CompareIntf<Dog>{
private String name;
private int age;
@Override
public void compare(Dog t) {
if(this.age > t.getAge()){
System.out.println(this.name+"比较大");
}else{
System.out.println(t.getName()+"比较大");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Dog() {
super();
// TODO Auto-generated constructor stub
}
public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
4.泛型方法
- 表示方法中有一个未知的类型
- 定义方法 : public 修饰符 返回值类型 方法名(){ }
- 可以在方法中使用T,表示一个类型
- 在调用方法时指定具体的类型
- 应用场景: 如果类和接口都没有定义泛型,但想在方法中使用泛型,此时可以定义为泛型方法
package javaSE12_泛型;
import java.util.Arrays;
public class Test03_泛型方法 {
public static void main(String[] args) {
Integer[] nums = {1,2,3,4,5};
// int[] newnums = Utils.change(nums, 0, 4);
Integer[] newnums = Utils.change2(nums, 0, 4);
System.out.println(Arrays.toString(newnums));
String[] arr ={"aa","bb","cc","dd"};
String[] newarr = Utils.change2(arr, 0, 3);
System.out.println(Arrays.toString(newarr));
}
}
class Utils{
/**
* 传入一个数组 以及两个下标,将下标对应的值进行交换,返回 交换后的新数组
* [1,2,3,4,5] 0 4 [5,2,3,4,1]
*/
public static int[] change(int[] nums,int x,int y){
int temp = nums[x];
nums[x]=nums[y];
nums[y]=temp;
return nums;
}
/**
* 泛型方法 可以满足多个种类的数组
* public 修饰符 <T> 返回值类型 方法名(){ }
* @param nums
* @param x
* @param y
* @return
*/
public static <T> T[] change2(T[] nums,int x,int y){
T temp = nums[x];
nums[x]=nums[y];
nums[y]=temp;
return nums;
}
}
5.泛型的特性
- 泛型的类型参数必须是引用类型
- 泛型的类型参数可以有多个
- 可以使用泛型通配符,两种<? extends 类型T> 参数类型必须是T或者T的子类 <? super 类型T> 参数类型必须是T或者T的父类
package javaSE12_泛型;
public class Test04_泛型的特性 {
public static void main(String[] args) {
C<Integer,Double,String> c = new C<>();
c.test(1, 1.2, "tom");
}
}
class C<T,K,V>{
public void test(T t,K k,V v){
System.out.println(t);
System.out.println(k);
System.out.println(v);
}
}
class D<T>{
public D<T> show(){
return new D<T>();
}
public D<? extends Pet> show2(){
return new D<Cat>();// <> 泛型只能是Pet 或者 子类
}
public D<? super Pet> show3(){
return new D<Pet>();//<> 泛型只能是Pet 或是 父类
}
}
class Pet{}
class Cat extends Pet{}
class Pig extends Pet{}