V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gramyang
V2EX  ›  Java

fastjson 和 eventbus 的两个奇葩的特性

  •  
  •   gramyang · 2019-05-21 18:03:28 +08:00 · 3420 次点击
    这是一个创建于 2015 天前的主题,其中的信息可能已经有所发展或是发生改变。

    fastjson: 只要用到构造器就必须手写一个空的构造器,不然报错。 这个问题貌似 1 点几的时候就有人反馈了,但是到现在还有。。。。

    eventbus: 基类注册了 eventbus,其子类必须要有带 @Subscribe 的方法,不然就崩溃。 如果我要去掉一个 fragment 或者 activity 上的事件监听,那我就得不继承基类,或者另外再写一个基类。 查了一下,人家说:你又不接受事件那你注册干嘛??我:好像很有道理。。

    14 条回复    2019-05-22 20:57:22 +08:00
    chendy
        1
    chendy  
       2019-05-21 18:33:23 +08:00
    jackson 也是一样,除非用了 @JsonCreator
    loshine1992
        2
    loshine1992  
       2019-05-21 18:40:21 +08:00
    你只要手写了构造方法,那么该类就不会默认有无参的构造方法了,json 序列化的库基本都是用无参构造生成一个实体,再一个一个根据反射设置参数,没有无参构造方法肯定报错啊。

    eventbus 的设计就是这样的,不要在基类里加可能用不到的东西。
    liuhuansir
        3
    liuhuansir  
       2019-05-21 18:44:34 +08:00   ❤️ 1
    eventbus 本来就不该在基类注册,很多人为了所谓的封装,在基类里写了一大堆东西,又臭又长
    Febers
        4
    Febers  
       2019-05-21 20:58:55 +08:00 via Android
    针对第二个,我的做法是提供一个 protected 方法,默认返回 false,然后在父类的 onCreate 代码中判断是否需要注册,如果子类不需要用到 eventBus 就重写该方法返回 false。当然我默认返回 false,毕竟子类用的不多
    Febers
        5
    Febers  
       2019-05-21 20:59:35 +08:00 via Android
    @Febers 第一个,默认返回 true
    clare0621
        6
    clare0621  
       2019-05-21 23:49:05 +08:00 via iPhone
    @Febers 你这种写法不如直接在子类注册
    Febers
        7
    Febers  
       2019-05-22 00:57:47 +08:00 via Android
    @clare0621 哈哈,强迫症吧,感觉 Eventbus 的调用挺长的,还要做判断是否注册过,不如交给父类,子类要么沿用父类,要么重写返回值
    gramyang
        8
    gramyang  
    OP
       2019-05-22 07:25:47 +08:00
    @Febers 我觉得这种方法挺好啊,所有的框架和设计模式不都是为了减少代码量而存在的吗
    MoHen9
        9
    MoHen9  
       2019-05-22 08:59:03 +08:00 via Android
    我看到在父类注册 EventBus 的,我就感觉很别扭,使用时自己注册不好吗,为了省那么点事。

    可以注册一个空的实现,不可能被调用的空方法。也可以判断一下,有返回就注册,没有就不注册
    no1xsyzy
        10
    no1xsyzy  
       2019-05-22 11:01:43 +08:00
    @gramyang 几乎所有的设计模式都会让代码量翻倍…… 只不过动脑写的少了,动手写的多了。
    这就像是 “四格漫画” 这种既定分镜或者媒体和官方的既定格式 “充分重视……严肃处理……” 一样。

    @Febers 难道不是 OnStart 注册,OnStop 解注吗?并且在第一次出现 Subscriber 的类里。
    我很难想象一个不需要任何监听任何消息的类继承自一个需要监听消息的类,正如我很难想象任何一小类杯子(即杯子的后代)里面不能装入液体(不继承 “装入液体” 的方法)一样。
    你可能说奖杯,但奖杯的父类显然是 “荣誉证明” 或者 “奖品” 之类的。
    所以我大胆主张你的问题来自错误的抽象。
    southsala
        11
    southsala  
       2019-05-22 11:17:32 +08:00
    EventBus 基类注册和取消注册前加个 boolean 开关,子类如果接收事件用 set 方法打开开关,这样对其他 Activity 和 Fragment 无感
    Febers
        12
    Febers  
       2019-05-22 13:40:31 +08:00 via Android
    @no1xsyzy 如果从“抽象”这个角度出发,这确实是错误的思想~我这么做的原因在于,举个例子,我有一个 BaseActivity,项目中所有 Activity 继承自它,为了让不同的 Activity 专注于自己的业务而不用每次都重写 onCreate setContentView inflate toolbar menu 以及延迟初始化,我选择让 Base 类拥有一个基于 if 判断的实现,然后定义可重写的方法,赋予子类自定义的接口。我通过这样的方式来“抽象”不同 Activity 共有或者需要的行为。

    好处在于,一方面子类的代码变少了,不用在每个子 Activity 里面做一些重复的工作,绑定视图只需要重写一个抽象方法 @override int setView() = R.layout.activity.main,如果需要注册时间总线,只需要 @override boolean registerBus() = true ……另一方面,日后更换总线实现(以及其他的实现)的时候也不用在每个已调用的 Activity 中修改,只需要更改 Base 中的代码即可。

    个人觉得这是一种编程的习惯,看个人喜好,也谈不上“设计模式”
    no1xsyzy
        13
    no1xsyzy  
       2019-05-22 20:25:44 +08:00
    我感觉
    一种你可以产生一个新的抽象层 BaseSubscriberActivity 继承自 BaseActivity,并且在这个类里进行所有的 register unregister 等,需要 Subscribe 的继承自 BaseSubscriberActivity,否则继承自 BaseActivity
    另一方面,我不太清楚 Java 的修饰器能做到什么程度,我觉得你更需要的是一个 @GeneralSubscriber 的类修饰器
    no1xsyzy
        14
    no1xsyzy  
       2019-05-22 20:57:22 +08:00
    @Febers 看上去 Java 要用 annotation 修改 class 的行为似乎很麻烦
    感觉是面向切面编程的一部分?相比之下 Python decorator 要方便得多,因为可以任意修改类属性,包括方法(本质上是类的一种静态属性,而 instance.method 会生成对应类方法的 bound method,并且实例可以覆盖它)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2749 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:21 · PVG 23:21 · LAX 07:21 · JFK 10:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.