目录
泛型概述
泛型可以让数据类型变的参数化:
- 定义泛型时候,对应的数据类型是不确定的
- 泛型方法被调用时,会指定具体类型
- 核心目标:解决容器类型在编译时的安全检查问题
下面的代码写的时候没有提示,但是编译的时候报错
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
public static void main(String[] args) {
List list = new LinkedList();
list.add(1);
list.add("2");
for (int i = 0; i < list.size(); i++) {
System.out.println((String) list.get(i));
}
}
加上泛型约束后,idea报出红线提示:
泛型类
class类名称<泛型标识:可以随便写任意标识号,标识指定的泛型,一般用T>
public class GenericClassExample<T> {
// member这个成员变量的类型也为T,T的类型由外部指定
private T member;
// 范型构造方法,形参的类型也为T,T的类型由外部指定
public GenericClassExample(T member) {
this.member = member;
}
public T handleSomething(T target){
return target;
}
public T getMember() {
return member;
}
public void setMember(T member) {
this.member = member;
}
}
class Test{
public static void main(String[] args) {
GenericClassExample<String> stringExample = new GenericClassExample<>("abc");
GenericClassExample<Integer> intExample = new GenericClassExample<>(123);
System.out.println(stringExample.getMember().getClass()); // class java.lang.String
System.out.println(intExample.getMember().getClass());// class java.lang.String
}
}
在泛型中使用有继承关系的类:
- 使用通配符?,但是会使得泛型的类型检查失去意义
- 给泛型加入上边界 ?exends E
- 给泛型加入下边界 ?super E
class Test{
public static void main(String[] args) {
GenericClassExample<Integer> intExample = new GenericClassExample<>(123);
System.out.println(intExample.getMember().getClass());// class java.lang.String
handleMember(intExample);
}
// 或le<? extends Number>改成<? super Integer>
public static void handleMember(GenericClassExample<? extends Number> intExample){
Integer result = 111 + (Integer) intExample.getMember();
System.out.println(result); //234
}
}
泛型接口
/**
* 定义范形接口
* @param <T>
* @param <N>
*/
public interface GenericFactory<T, N> {
T nextObject();
N nextNumber();
}
// 泛型接口实现类
class RobotFactory implements GenericFactory<String, Integer> {
private String[] stringRobot = new String[]{"Hello", "Hi"};
private Integer[] integerRobot = new Integer[]{100, 200};
@Override
public String nextObject() {
// 随机返回一个元素
return stringRobot[new Random().nextInt(2)];
}
@Override
public Integer nextNumber() {
// 随机返回一个元素
return integerRobot[new Random().nextInt(2)];
}
public static void main(String[] args) {
GenericFactory<String, Integer> factory = new RobotFactory();
System.out.println(factory.nextNumber());
System.out.println(factory.nextObject());
}
}
泛型方法
public static void main(String[] args) {
Integer[] integers = {1,2,3};
Character[] characters = {'A','B','C'};
printArray(integers);
printArray(characters);
}
public static<E> void printArray(E[] inputArray){
for (E element : inputArray) {
System.out.print(element); //123ABC
}
}
常用示例
返回前端工具类:
//保证序列化json的时候,如果是null的对象,key也会消失
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ServerResponse<T> {
/**
* 状态
*/
private int status;
/**
* 提示信息
*/
private String msg;
/**
* 数据
*/
private T data;
private ServerResponse(int status){
this.status = status;
}
private ServerResponse(int status,T data){
this.status = status;
this.data = data;
}
private ServerResponse(int status,String msg,T data){
this.status = status;
this.msg = msg;
this.data = data;
}
private ServerResponse(int status,String msg){
this.status = status;
this.msg = msg;
}
public int getStatus(){
return status;
}
public T getData(){
return data;
}
public String getMsg(){
return msg;
}
public static <T> ServerResponse<T> createBySuccess(){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
}
public static <T> ServerResponse<T> createBySuccessMessage(String msg){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg);
}
public static <T> ServerResponse<T> createBySuccess(T data){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),data);
}
public static <T> ServerResponse<T> createBySuccess(String msg,T data){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg,data);
}
public static <T> ServerResponse<T> createByError(){
return new ServerResponse<T>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc());
}
public static <T> ServerResponse<T> createByErrorMessage(String errorMessage){
return new ServerResponse<T>(ResponseCode.ERROR.getCode(),errorMessage);
}
public static <T> ServerResponse<T> createByErrorCodeMessage(int errorCode,String errorMessage){
return new ServerResponse<T>(errorCode,errorMessage);
}
}