泛型
大约 2 分钟languagejava
案例
运行时具体类型
获取调用时传入的类型后可以创建实例对象,获取类型的属性,通过反射调用类型的方法,具体使用见仓库 https://gitee.com/chanchaw/my-orm 的类 MBBaseServiceImpl
public class MBBaseServiceImpl<T> implements BaseService<T> {
@Autowired
private BaseMapper mapper;
@Override
public List<T> queryList(Object obj) throws InvocationTargetException, IllegalAccessException, SQLException, InstantiationException {
final ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
Class<T> modelClass = (Class<T>)type.getActualTypeArguments()[0];
// 上面的 modelClass 是调用类 MBBaseServiceImpl 时传入的具体类型
// 使用本类型可以创建对应的实例对象
T newRecord = modelClass.newInstance();
// 也可以获取类型拥有的属性,然后通过反射调用 getter,setter 方法
Field[] fields = modelClass.getDeclaredFields();
// 下面是小驼峰模式下,获取 getter,setter 方法名称
public static String getGetterMethodName(Object obj,Field field){
String fieldName = field.getName();
return "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
}
public static String getSetterMethodName(Field field){
return "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
}
泛型方法
public static <T> T removeObjNoSentidoAndBlank(T record){
// 通过反射遍历属性,处理所有字符串类型的属性
Class<?> aClass = record.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for(Field item:declaredFields){
item.setAccessible(true);
boolean b = item.getGenericType().toString().equalsIgnoreCase("class java.lang.String");
if(b){
try {
String strVal = (String)item.get(record);
strVal = StringUtils.removeNoSentidoAndBlank(strVal);
item.set(record,strVal);
} catch (IllegalAccessException e) {
System.out.println("移除对象["+record+"]的属性["+item.getName()+"]的回车换行符时出现异常!");
}
}
}
return record;
}
泛型参数的类类型
下面方法通过第三个参数传入泛型的类类型同时返回该泛型的对象
package com.xdf.wxpad.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.Map;
/**
* @author chanchaw
* @create 2024-09-02 8:58
*/
@Component
public class RestTemplateUtils {
@Resource
private RestTemplate restTemplate;
public <T> T postJson(String url, Map<String, Object> param, Class<T> responseType) throws JsonProcessingException {
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
ObjectMapper mapper = new ObjectMapper();
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String paramJsonString = ow.writeValueAsString(param);
HttpEntity<String> formEntity = new HttpEntity<>(paramJsonString, headers);
String responseJsonString = restTemplate.postForObject(url, formEntity, String.class);
return mapper.readValue(responseJsonString, responseType);
}
}
// 调用方法
CallTemplateMsgRes callRes = restTemplateUtils.postJson(reqUrl, BeanMap.create(msg), CallTemplateMsgRes.class);
下面将上面案例简化
public <T> T get4Object(String url, Class<T> responseType) {
return restTemplate.getForObject(url, responseType);
}
// 获取 String 类型的响应
String url = "http://example.com";
String response = get4Object(url, String.class);
// 获取 Integer 类型的响应
Integer intResponse = get4Object(url, Integer.class);
