今天看netty源码时,发现一种针对泛型进行数据过滤的处理方法。简单代码如下所示:
public class EchoClientHandler extends SimpleChannelInboundHandlerAdapter<ByteBuf> {
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
System.out.println("Client received" + ByteBufUtil.hexDump(in.readBytes(in.readableBytes())));
}
}
这个代码的意思就是只有当数据的类型为ByteBuf类型时,才能够进入这个方法,并调用相应的channelRead0方法。从实现的角度来看就是这个方法在执行时,会进行类型以下的一个判断
if(data instanceOf ByteBuf) {
//todo do something
}
这就意味着在代码中,是可以拿到这个泛型参数的。并且可以利用这个泛型参数作一些特别的处理,或者参与业务逻辑。在传统的类型过虑处理中,我们通常会实现以下的一个方法来表示,当前处理类需要支持哪一种类型的数据信息。
//声明接口方法
public Class<?> supportType() {
return Sth.class;
}
//调用代码
Object param = someData;
for(Impl impl : implList) {
if(impl.supportType().isAssignableFrom(param.getClass)) {
//then do logic
}
}
那么如果采用泛型,这个多余的supportType方法就可以省略,意味着可以直接将相应的参数添加到类签名上。然后直接进行解析即可。这样就不需要再每个实现类写多余的实现方法了。
解析泛型签名信息
相比原netty中的仔细实现,这里仅将其主要实现列出如下,就可以拿到相应的泛型信息了。
//声明了个子类的实体
ParameterizedTypeTest t = new ParameterizedTypeTest<Map>() {};
ParameterizedType type = (ParameterizedType) t.getClass().getGenericSuperclass();
System.out.println(type.getActualTypeArguments()[0]);
这里,我们通过当前子类的的getGenericSuperclass方法拿到它的泛型父类信息。这里的返回值为type,并且它的值也不等于getSuperClass。因为我们可以肯定它的泛型父类是一个参数化类型,这里通过获取泛型类型的第一个实际参数就可以拿到相应的类型。
注意,这里仍然返回Type类型,因为我们这里简化判断,就认为可以是一个Class类型。这样就获取到相应的类型。
如果相应的代码是这样写的:
//声明了个子类的实体
ParameterizedTypeTest t = new ParameterizedTypeTest<Map<?,List>>() {};
ParameterizedType type = (ParameterizedType) t.getClass().getGenericSuperclass();
//这里的实际Type就不再是一个class,而是一个parameterizedType
System.out.println(((ParameterizedType)type.getActualTypeArguments()[0]).getRawType());
这里返回的type.getActualTypeArguments()[0] 就不再是一个class类型,而是一个表示Map<?,List>的泛型信息。而我们需要从这个泛型信息中查找相应的原始类型,即声明这个泛型的声明类,即Map类。这也是在netty中的查找方式。原代码如下所示:
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments();
Type actualTypeParam = actualTypeParams[typeParamIndex];
//参数化类型如何处理 直接返回声明类
if (actualTypeParam instanceof ParameterizedType) {
actualTypeParam = ((ParameterizedType) actualTypeParam).getRawType();
}
//直接是一个类如何处理,如果返回之
if (actualTypeParam instanceof Class) {
return (Class<?>) actualTypeParam;
}
//是一个数组类处理 直接返回数组声明类
if (actualTypeParam instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) actualTypeParam).getGenericComponentType();
if (componentType instanceof ParameterizedType) {
componentType = ((ParameterizedType) componentType).getRawType();
}
if (componentType instanceof Class) {
return Array.newInstance((Class<?>) componentType, 0).getClass();
}
}
//是一个类型声明变量
if (actualTypeParam instanceof TypeVariable) {
......
}
其实就是通过if判断是否是指定的类型,通过向下转型然后再拿到实际想到拿到的类型信息。拿到类型之后,我们的一些泛型化编程就可以再进一步,用泛型声明来表示实际的类型信息,然后将其参与到具体的业务逻辑当中,以达到简化代码,使代码更简洁,清晰的目的。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/java-programe/201406100001.html