使用泛型进行类型的过滤和处理

今天看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

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

电子邮件地址不会被公开。 必填项已用*标注