热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中的通用protobuf解串器

如何解决《Java中的通用protobuf解串器》经验,为你挑选了1个好方法。

我正在尝试编写一个通用的Java类,该类可用于反序列化/解析任何protobuf消息。

以下是代码在理想环境中的外观:

public abstract class ProtoDeserializer {

    public T deserialize(final byte[] bytes) throws Exception {     
        Parser parser = T.getParserForType(); // Syntax Error: this method is not static!

        T message = parser.parseFrom(bytes);
        validate(message);
        return message;
    }

    public abstract void validate(final T message) throws Exception;
}

但是,我无法获得通用protobuf消息的正确解析器。实现此类泛型类的正确方法是什么?



1> Jorn Vernee..:

最简单的方法是将解析器作为参数传递给构造函数:

public abstract class ProtoDeserializer {

    private final Parser parser;

    public ProtoDeserializer(Parser parser) {
        this.parser = parser;
    }

    public T deserialize(final byte[] bytes) throws Exception {    
        T message = parser.parseFrom(bytes);
        validate(message);
        return message;
    }

    public abstract void validate(final T message) throws Exception;
}

通过解析器是我当前的解决方法。但是最好避免使用它,因为它是多余的信息。

这对您可能是多余的,但对编译器/运行时却不是多余的。

如果您认为可以创建类的原始实现:

ProtoDeserializer proto = new ProtoDeserializer() {
    ...
};

该类型T必须来自某个地方

这只是已删除的泛型的事实。如果需要通用参数的类型信息,则必须手动提供它。


另一个黑客可以尝试是从一个执行子类得到具体的类型参数:

private final Parser parser; 

public ProtoDeserializer() {
    Class subclass = this.getClass();

    try {
        ParameterizedType pType = (ParameterizedType) subclass.getGenericSuperclass();
        Class tClass = (Class) pType.getActualTypeArguments()[0];
        // In the case where the constructor for `T` takes no arguments.
        parser = tClass.newInstance().getParserForType();
    } catch(Throwable t) {
        throw new RuntimeException("Subclass not compatible", t);
    }
}

只要子类直接ProtoDeserializer使用具体的类型实参实现,此方法就可以工作。即:

class MyDeserializer extends ProtoDeserializer {...}


推荐阅读
  • Java 架构:深入理解 JDK 动态代理机制
    代理模式是 Java 中常用的设计模式之一,其核心在于代理类与委托类共享相同的接口。代理类主要用于为委托类提供预处理、过滤、转发及后处理等功能,以增强或改变原有功能的行为。 ... [详细]
  • Java中String类为何设计为final?其不可变性与其他包装类的特性
    探讨Java中String类设计为final的原因及其不可变性,同时分析其他基本数据类型包装类及枚举类型的不可变性。 ... [详细]
  • 本文介绍了一个项目中如何在Windows平台上实现多声道音频数据的采集,特别是针对DANTE音频接口的8路立体声音频通道。文章详细描述了使用Windows底层音频API进行音频采集的方法,并提供了一个具体的实现示例。 ... [详细]
  • MainActivityimportandroid.app.Activity;importandroid.os.Bundle;importandroid.os.Handler;im ... [详细]
  • Java EE CDI:解决依赖关系冲突的实例
    在本教程中,我们将探讨如何在Java EE的CDI(上下文和依赖注入)框架中有效解决依赖关系的冲突问题。通过学习如何使用限定符,您将能够为应用程序的不同客户端提供多种接口实现,并确保每个客户端都能正确调用其所需的实现。 ... [详细]
  • 在Java应用程序开发过程中,FTP协议被广泛用于文件的上传和下载操作。本文通过Jakarta Commons Net库中的FTPClient类,详细介绍如何实现文件的上传和下载功能。 ... [详细]
  • ▶书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall算法可能含负环的有边权有向图任意两点之间的最短路径●有边权有向图的邻接矩阵1 ... [详细]
  • 1Authenticator简介1.1层次结构图1.2作用职责是验证用户帐号,是ShiroAPI中身份验证核心的入口点;接口中声明的authenticate方法就是用来实现认证逻辑 ... [详细]
  • 本文将指导如何在JFinal框架中快速搭建一个简易的登录系统,包括环境配置、数据库设计、项目结构规划及核心代码实现等环节。 ... [详细]
  • 大数据基础:JavaSE_day06 ... [详细]
  • 在Java开发中,使用BASE64编码通常可以直接利用JDK内置的库。然而,在Android平台上,由于安全性和兼容性的考虑,直接引用JDK中的`sun.misc.BASE64Decoder`会导致错误,因此需要引入第三方库来实现相同的功能。 ... [详细]
  • Java性能优化策略详解
    在Java开发中,性能优化是提高应用程序响应速度和资源利用率的关键。本文详细探讨了多种Java性能优化技巧,包括合理使用单例模式、避免滥用静态变量、减少对象创建、使用final修饰符、合理管理线程同步等,旨在帮助开发者写出更加高效稳定的代码。 ... [详细]
  • Android中解析XML文件的实践指南
    本文详细介绍了在Android应用开发中解析XML文件的方法,包括从本地文件和网络资源获取XML文件的不同途径,以及使用DOM、SAX和PULL三种解析方式的具体实现。 ... [详细]
  • 最近同事提了一个需求过来,他觉得项目对于第三方日志记录的太多了,只想记录一些业务相关的日志减少对于框架日志的显示。具体要求就是对于框架日志只显示warn等级以上的,而业务日志显示info等级以上 ... [详细]
  • 本文探讨了Java中char数据类型的特点,包括其表示范围以及如何处理超出16位字符限制的情况。通过引入代码点和代码单元的概念,详细解释了Java处理增补字符的方法。 ... [详细]
author-avatar
DilWilling
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有