没有java泛型会存在的问题
- 假设我们有一个方法,希望通过传递不同类型的参数,输出不同类型的对象值。正常情况下我们可能会写不同的方法来实现,但是这样会导致类不断增加,并且类方法很相似,不能够复用。进而导致类爆炸
- 假设有一个方法,我们希望传参具有一定约束,而不是像Object对象一样随便传参
java泛型的常见使用
包装类型参数
- 定义一个方法,打印各种包装类型
public class Generics1<T> {private T name;public Generics1(T name) {this.name = name;}public void allPrint(){System.out.println(name);}
}
- main
public class Main {public static void main(String[] args) {Generics1<Integer> integerGenerics1 = new Generics1<>(1);integerGenerics1.allPrint();Generics1<String> stringGenerics2 = new Generics1<>("222222");stringGenerics2.allPrint();Generics1<Long> longGenerics3 = new Generics1<>(222L);longGenerics3.allPrint();}
}
注意:泛型里面必须是对象,或者包装类型。基础类型是不被允许的
多个包装类型参数
- 两个泛型参数
public class Generics2<T,K> {private T name;private K context;public Generics2(T name,K context) {this.name = name;this.context=context;}public void allPrint(){System.out.println(name);System.out.println(context);}
}
- Main
public class Main2 {public static void main(String[] args) {Generics2<String, Integer> stringIntegerGenerics2 = new Generics2<>("1111", 222);stringIntegerGenerics2.allPrint();}
}
上界继承
- 限定使用者传递的参数必须继承某个父类之下
public class Generics3<T extends Vehicle> {private T name;public Generics3(T name) {this.name = name;}public void allPrint(){System.out.println(name.getName());}
}
- 父类
public class Vehicle {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void run(String name){System.out.println(name+"can run");}
}
- 子类
public class Car extends Vehicle{private Integer wheel;public Integer getWheel() {return wheel;}public void setWheel(Integer wheel) {this.wheel = wheel;}public void getWheel(String name,Integer wheel) {System.out.println(name+"有"+wheel+"个轮子");}
}
- 可以不是父 类,可以是接口。接口有更好的扩展性
public class Generics4<T extends Vehi> {private T vehics;public Generics4(T vehics) {this.vehics = vehics;}public void allPrint(){vehics.run();}
}
- 接口
public interface Vehi {void run();
}
使用上界继承的好处
- 使用上界继承的最大好处是:必然我们会用到接口或者父类,那么我们可以抽取一些公共方法,放到父类或接口里面。不同的实现拥有不同的处理方式。具备更强的扩展性
- java里面虽然有Object来实现传递各种类型参数(如下),但是不推荐这么做。会产生一种。例如:当我们从List取值的时候,java是无法推断里面值的类型,编译器就会报错
上面这个代码在运行时,获取第二个值时,就会报错。
使用Object,在编译阶段是没有问题的,但是在运行时就会出现问题。
而使用泛型,在编译阶段,就能检查出来问题
泛型函数:Generic method
泛型函数方法的定义
- 在返回类型前添加泛型类型: 。参数设置为泛型
private static <T> void printAll(T myOb){
}
- 举例子
public class Main5 {public static void main(String[] args) {printAll(new BigCar(3,"myba"));}private static <T> void printAll(T myOb){System.out.println(myOb);}
}
- 同理也可以使用上界继承限定
private static <T> void printAll(T myOb){System.out.println(myOb);}
private static <T extends Vehicle & Vehi> void printAll(T myOb){System.out.println(myOb);
}
- 配置多个参数
private static <T,K> void printAll2(T myOb,K myob2){System.out.println(myOb);System.out.println(myob2);
}
泛型通配符
- String,Integer,Long我们在传递参数时,可以用Object来定义参数。但是:List,却不是List的子类。这种情况怎么处理?
- 通配符的使用
private static void printAll(List<?> myOb){System.out.println(myOb);
}
上界通配符
- 意思是,传入的参数必须是Vehi的子类或者实现,或者本身
private static void printAll(List<? extends Vehi> myOb){System.out.println(myOb);
}
下界通配符
- 意思是传入的参数必须是Car的父类或者Car本身
private static void printAll(List<? super Car> myOb){System.out.println(myOb);
}