
ParameterizedType 是泛型/参数化类型,其定义如下:
public interface java.lang.reflect.ParameterizedType extends Type {
Type[] getActualTypeArguments();
Type getRawType();
Type getOwnerType();
}
ParameterizedTypeImpl 实现类
public class ParameterizedTypeImpl implements ParameterizedType {
private final Type[] actualTypeArguments;
private final Class> rawType;
private final Type ownerType;
private ParameterizedTypeImpl(Class> var1, Type[] var2, Type var3) {
this.actualTypeArguments = var2;
this.rawType = var1;
this.ownerType = (Type)(var3 != null ? var3 : var1.getDeclaringClass());
this.validateConstructorArguments();
}
private void validateConstructorArguments() {
TypeVariable[] var1 = this.rawType.getTypeParameters();
if (var1.length != this.actualTypeArguments.length) {
throw new MalformedParameterizedTypeException();
} else {
for(int var2 = 0; var2 < this.actualTypeArguments.length; ++var2) {
}
}
}
public static ParameterizedTypeImpl make(Class> var0, Type[] var1, Type var2) {
return new ParameterizedTypeImpl(var0, var1, var2);
}
}
ParameterizedType的方法有什么?
- Type[] getActualTypeArguments()
注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。
返回:
表示此类型的实际类型参数的 Type 对象的数组
- Type getRawType()
返回 Type 对象,表示声明此类型的类或接口。
返回:
Type 对象,表示声明此类型的类或接口
- Type getOwnerType()
返回 Type 对象,表示此类型是其成员之一的类型。例如,如果此类型为 O
.I ,则返回 O的表示形式。 如果此类型为顶层类型,则返回 null。
返回:
Type 对象,表示此类型是其成员之一的类型。如果此类型是顶层类型,则返回 null
以下演示ParameterizedType的属性值,通过实例打印出方法的返回结果,我们先定义如下的对象。
@Data
class Person {
private String name;
private Integer age;
}
@Data
public class SingleResponse {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
@Data
class Holder {
private List list;
SingleResponse response;
private Map.Entry map;
}
单元测试类如下;
@Test
public void testParameterizedMethod() {
Holder holder = new Holder();
Field[] fields = holder.getClass().getDeclaredFields();
for (Field field : fields) {
//返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。
//如果 Type 是一个参数化类型,则返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
Type[] actualTypes = pt.getActualTypeArguments();
Type ownerType = pt.getOwnerType();
Type rawType = pt.getRawType();
StringBuilder sb = new StringBuilder();
sb.append("actualTypes :");
for (Type item : actualTypes) {
sb.append(item.getTypeName() + ", ");
}
System.out.println(sb);
System.out.println("ownerType : " + ownerType);
System.out.println("rawType :" + rawType);
System.out.println("--------------------");
}
}
}
程序输出结果:
actualTypes :java.lang.String, ownerType : null rawType :interface java.util.List -------------------- actualTypes :com.jd.flow.reflect.ParameterizedTypeTest$Person, ownerType : null rawType :class com.jd.cjg.flow.dto.SingleResponse -------------------- actualTypes :java.lang.Integer, java.lang.String, ownerType : interface java.util.Map rawType :interface java.util.Map$Entry --------------------ParameterizedType 在HTTP API中的使用
在Http Restful Api接口中,我们通常使用一个响应的包装类来统一我们的HTTP响应结果。如下定义
public class SingleResponse{ private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } public static SingleResponse success() { SingleResponse response = new SingleResponse(); response.setSuccess(true); return response; } public static SingleResponse success(T data) { SingleResponse response = new SingleResponse<>(); response.setSuccess(true); response.setData(data); return response; } public static SingleResponse failure(String errCode, String errMessage) { SingleResponse response = new SingleResponse(); response.setSuccess(false); response.setCode(errCode); response.setMessage(errMessage); return response; } }
我们模拟接收到响应的JSON数据转包装类的 测试。
@Test
public void testRestful() {
// 申请单Client Object
FlowReqCO flowReqCO = new FlowReqCO();
flowReqCO.setReqId("12344");
flowReqCO.setApplyUser("yangyanping");
SingleResponse response = SingleResponse.success(flowReqCO);
//模拟 Restful API json 结果
String body = JSON.toJSonString(response);
// 模拟客户端获取到json 转换对象
Type parameterizedTypeClass = ParameterizedTypeImpl.make(SingleResponse.class, new Type[]{FlowReqCO.class}, null);
response = JSON.parseObject(body, parameterizedTypeClass);
System.out.println(response.getData().getReqId());
}
ParameterizedType 在工厂方法模式中的应用
在一些较复杂的业务中,如果我们把大量的业务逻辑代码堆砌到服务中,会导致服务方法任何一个的变更都会引起服务类的变更,违反单一职责原则
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。
我们可以借鉴Spring MVC Controller的处理方式,使用委派模式把请求转发给一个Executor处理器去执行,代码如下:
我们先定义抽象的处理器接口:
public abstract class CommandExecutor{ private final Class> requestType; public CommandExecutor() { Type type = this.getClass().getGenericSuperclass(); ParameterizedType pt = (ParameterizedType) type; Type[] actualTypes = pt.getActualTypeArguments(); this.requestType = actualTypes[0].getClass(); } public Class> getRequestType() { return requestType; } public abstract S execute(R cmd); }
具体的创建申请单命令处理器
public class FlowReqSubmitCommandExecutor extends CommandExecutor{ @Override public String execute(FlowReqSubmitCommand cmd) { return "创建申请单成功"; } }
单元测试:
@Test
public void testExecutor(){
FlowReqSubmitCommandExecutor executor = new FlowReqSubmitCommandExecutor();
String result = executor.execute(new FlowReqSubmitCommand());
System.out.println(result);
}
我们还可以定义一个处理器工厂,在Spring 启动完成后缓存所有的处理器类
@Slf4j public class CommandFactory implements ApplicationContextAware, InitializingBean, ApplicationListener{ private static final AtomicBoolean initFlag = new AtomicBoolean(); private static ApplicationContext applicationContext; private static Map , CommandExecutor> commandExecutorMap = Maps.newHashMap(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() throws Exception { this.register(); } @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { log.info("CommandFactory spring start!"); } public static CommandExecutor getExecutor(Class> claz) { return commandExecutorMap.get(claz); } public static CommandExecutor getExecutor(Command command) { return commandExecutorMap.get(command.getClass()); } private void register() throws Exception { if (!initFlag.compareAndSet(false, true)) { return; } Map beanMap = applicationContext.getBeansOfType(CommandExecutor.class); for (Map.Entry entry : beanMap.entrySet()) { CommandExecutor commandExecutor = entry.getValue(); commandExecutorMap.put(commandExecutor.getRequestType(), commandExecutor); } } }
根据命令Command 查找处理器并执行请求
@Test
public void testCommandFactory() {
FlowReqSubmitCommand cmd = new FlowReqSubmitCommand();
CommandFactory.getExecutor(cmd).execute(cmd);
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)