泛型
1、概述
是一种把类型明确的工作,推迟到创建对象,或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
2、格式
<数据类型> 这里的数据类型只能是引用数据类型
3、泛型好处
(1): 把运行时期的问题提前到了编译期间
(2): 避免了强制类型转换
(3):优化了程序设计,解决了黄色警告线
注意:泛型只在编译期有效 但在运行期就擦除了
ArrayList<Object> list = new ArrayList<>();
list.add(100);
list.add("abc");
Object o = list.get(0);
Object o1 = list.get(1);
用泛型ArrayList存储自定义对象并遍历
ArrayList<Object> list = new ArrayList<>();
list.add(100);
list.add("aaa");
list.add(300);
list.add(500);
list.add("SOC");
list.add(100);
list.add("abc");
list.add(855);
list.add("GPU");
Iterator<Object> iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
4、泛型的由来
通过Object转型问题引入早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
泛型类
1、概述:把泛型定义在类上
2、格式:public class 类名<泛型类型1,…>
注意泛型类型必须是引用类型
public class MyObject<M,N> { //将泛型加在类上面
private M m;
private N n;
public M getM(){
return m;
}
public void setM(M m){
this.m=m;
}
public N getN(){
return n;
}
public void setN(N n){
this.n=n;
}
}
MyObject<Object, Object> obj = new MyObject<>();
obj.setM(100);
obj.setN("abc");
Object m = obj.getM();
Object n = obj.getN();
System.out.println(m+" "+n);//100 abc
泛型方法
1、概述:把泛型定义在方法上
2、格式:public<泛型类型> 返回类型 方法名(泛型类型 变量名)
public class Test {
public static void main(String[] args) {
Integer m = 3;
show(m);//3
String n = "abc";
show(n);//abc
}
public static <M> void show(M m){
System.out.println(m);
}
}
泛型接口
1、概述:把泛型定义在接口上
2、格式:public interface 接口名<泛型类型>
泛型接口的子类: 第一种情况: 就是在定义子类的时候我们已经可以明确数据类型了
public interface TestInterface<X,Y,M> {
public X add(Y y,M m );
}
public class Test implements TestInterface<Integer,Integer,Integer>{
public Integer add(Integer integer1,Integer integer2){
Integer integer = integer1+integer2;
return integer;
}
public static void main(String[] args) {
Test test = new Test();
Integer add = test.add(100, 200);
System.out.println(add);//300
}
}
public class Test2{
public static void main(String[] args) {
//使用匿名内部类,在创建接口的子类对象时,如果接口上加有泛型,那么需要明确泛型的具体类型
new TestInterface<Integer,Integer,Integer>(){
public Integer add(Integer integer1,Integer integer2){
Integer integer = integer1+integer2;
return integer;
}
};
}
}
泛型接口的子类: 第二种情况: 就是在定义子类的时候我们还不知道到底使用神马数据类型.这个时候我们就需要将这个子类也定义
public interface TestInterface<X,Y,M> {
public void add(X x,Y y,M m );
}
public class Test<X,Y,M>implements TestInterface<X,Y,M>{
public void add(X x,Y y,M m){
System.out.println(x+" "+y+" "+m);
}
}
泛型通配符
泛型通配符<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E: 向下限定,E及其子类
? super E: 向上限定,E及其父类
注意:泛型如果明确了数据类型以后,要求左右两边的数据类型必须一致
import java.util.ArrayList;
public class Test2{
public static void main(String[] args) {
//泛型通配符
ArrayList<?> objects = new ArrayList<>();
//向上限定
ArrayList<? super Animal> objects1 = new ArrayList<Animal>();
ArrayList<? super Animal> objects2 = new ArrayList<Object>();
//向下限定
ArrayList<? extends Animal> objects3 = new ArrayList<Animal>();
ArrayList<? extends Animal> objects4 = new ArrayList<Dog>();
ArrayList<? extends Animal> objects5 = new ArrayList<Cat>();
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}