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

Map, List 写死类型和不写有什么区别?

  •  
  •   aoscici2000 · 2019-06-18 16:53:32 +08:00 · 4975 次点击
    这是一个创建于 2019 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如我传入的数据{"name": "...", "age": 90 ...}

    1: public String saveOne(Map<String, Object> data) { ... }

    2: public String saveOne(Map data) { ... }

    1 和 2 有什么区别?

    34 条回复    2019-08-05 16:59:52 +08:00
    CFO
        1
    CFO  
       2019-06-18 17:03:19 +08:00 via Android
    了解下泛型的作用
    krisuari
        2
    krisuari  
       2019-06-18 17:07:48 +08:00
    看业务 如果没有共性,可以写死。
    考虑通用或者底层就不要硬编码
    wenzhoou
        3
    wenzhoou  
       2019-06-18 17:16:11 +08:00 via Android   ❤️ 1
    肯定第一种,因为你的 key 是 String 嘛。
    wolfie
        4
    wolfie  
       2019-06-18 17:17:28 +08:00
    不指定类型,迭代时候强转吗。
    Mistwave
        5
    Mistwave  
       2019-06-18 17:19:09 +08:00 via iPhone
    effective java 3rd
    item 26
    wolfie
        6
    wolfie  
       2019-06-18 17:21:43 +08:00
    实际没区别。
    ```
    List<String> l1 = new ArrayList();

    List l2 = l1;
    l2.add(new Integer(1));

    System.out.println(l2.get(0) instanceof Integer);
    ```
    wenzhoou
        7
    wenzhoou  
       2019-06-18 17:46:14 +08:00 via Android
    这样写代码的话容易菊花不保啊。
    wc951
        8
    wc951  
       2019-06-18 18:00:03 +08:00 via Android   ❤️ 1
    ide 会给出 rawtype 警告,逼死强迫症
    SpiderXiantang
        9
    SpiderXiantang  
       2019-06-18 18:01:49 +08:00
    阅读一下 java 编程思想 以及了解一下向上转型
    aoscici2000
        10
    aoscici2000  
    OP
       2019-06-18 18:12:20 +08:00
    @wenzhoou 为何?
    SabaPing
        11
    SabaPing  
       2019-06-18 18:12:54 +08:00
    首先这样做本质上是为了做到 static type safety + polymorphism , 换句话说在保证一定静态类型安全前提下, 抽出共性, 代码重用.

    然后 polymorphism 中有一大类叫做 parameter polymorphism, java list 的泛型就是 parameter polymorphism 的一种实现.
    wenzhoou
        12
    wenzhoou  
       2019-06-18 18:22:24 +08:00 via Android
    @aoscici2000 我是说 6 楼。这样写没法维护。
    NoKey
        13
    NoKey  
       2019-06-18 18:23:28 +08:00
    不看你这帖子,我都不知道居然有第二种写法
    kaedea
        14
    kaedea  
       2019-06-18 18:25:33 +08:00 via Android
    等价
    具体可以了解静态类型安全、泛型、型变
    chendy
        15
    chendy  
       2019-06-18 18:29:00 +08:00
    除非有特殊需求,否则用 Map 接 json 的,见一个打死一个…
    u823tg
        16
    u823tg  
       2019-06-18 18:43:32 +08:00 via Android
    直接接 json,真的勇士啊你
    palmers
        17
    palmers  
       2019-06-18 18:43:41 +08:00
    区别在于使用者是否能够已知数据类型,如果在 saveOne 方法内部需要把数据取出来做一些业务逻辑,那显然第一种是最优雅的解决方案, 编译期不用强转,数据类型也很明显, 如果 saveOne 内完全不关心数据类型或者处理数据不用关心具体的数据类型 那其实都一样,但是从编码上来说第一种是最好,java 引入泛型目的之一是为了安全 减少 bug

    所以总体来说第一种最好
    woodensail
        18
    woodensail  
       2019-06-18 18:47:56 +08:00
    对于代码运行实际上是没有区别的,毕竟泛型信息在编译时就被擦除了。
    指定泛型的左右实际上是在写代码的时候帮助进行代码分析和提示,以及在编译阶段就把可能出错的地方报出来。

    如果一个已完成项目里面本身都指定了泛型信息,这时候把所有泛型全部删掉,和之前运行起来不会有区别(反射炫技除外),只是少了一堆代码提示和多了一堆强制类型转换。
    toconoma
        19
    toconoma  
       2019-06-18 18:50:03 +08:00
    好好地写个类很难吗...
    aoscici2000
        20
    aoscici2000  
    OP
       2019-06-18 19:01:50 +08:00 via iPhone
    @chendy 为什么?接到合格数据就处理,不合格就返回去指明格式要求,好像也没什么毛病的样子?
    chendy
        21
    chendy  
       2019-06-18 20:19:10 +08:00
    @aoscici2000 必须要找到所有的 get 和 put 否则不知道里面有什么
    Raymon111111
        22
    Raymon111111  
       2019-06-18 20:39:15 +08:00
    从代码运行的角度是完全没区别的

    但是还推荐加, 因为可以保证传入的类型, 你也不希望你认为 get 出一个 String 结果是个 int 吧
    gam2046
        23
    gam2046  
       2019-06-18 20:39:56 +08:00
    对于 Java 来说没有任何区别,Java 的泛型是基于类型擦除实现的,本身就是一个伪泛型,只是编译器帮你做了强制类型转换。
    cheng6563
        24
    cheng6563  
       2019-06-18 20:41:44 +08:00 via iPhone
    @chendy map 接 json 有啥问题啊
    zjsxwc
        25
    zjsxwc  
       2019-06-18 20:44:20 +08:00 via Android
    用朴素的解释来说区别就是,
    被调用者 与 调用者 之间的“约定” 不一样,
    如果被调用者完全不关心入参具体类型,例如仅仅只是做数值运算或者缓存等,那么用 Map ;
    如果被调用者对入参具体类型有要求,那么用对应 json 字符串的 Class,别用 Map<String, Object>;


    楼主的 saveone 明显是数据库操作
    zjsxwc
        26
    zjsxwc  
       2019-06-18 20:44:52 +08:00 via Android
    楼主的 saveone 明显是数据库操作,还用 map 不是找骂吗?
    aoscici2000
        27
    aoscici2000  
    OP
       2019-06-18 21:10:15 +08:00 via iPhone
    @zjsxwc 传进来的数据一大堆数组需要计算后才保存,感觉直接用 map 还方便点,确实被骂了一顿...
    luozic
        28
    luozic  
       2019-06-18 21:12:19 +08:00 via iPhone
    JMH 基准测试一下。
    20015jjw
        29
    20015jjw  
       2019-06-18 23:14:14 +08:00 via Android
    学一下基本的东西再写啊..
    aoscici2000
        30
    aoscici2000  
    OP
       2019-06-18 23:54:21 +08:00
    @20015jjw 呃...基础都看了,看完就容易忘了, 难道边写边学不是比较有效的方式嘛
    Takamine
        31
    Takamine  
       2019-06-18 23:55:03 +08:00 via Android
    不如形参类型也都用 Object o 好了。:doge:
    HongJay
        32
    HongJay  
       2019-06-18 23:58:50 +08:00
    @aoscici2000 所以被喷也要坦然接受。
    EminemW
        33
    EminemW  
       2019-06-19 01:10:10 +08:00 via iPhone
    想知道为什么接 json 不直接用 JSONObject
    nnnToTnnn
        34
    nnnToTnnn  
       2019-08-05 16:59:52 +08:00
    没啥区别,最后编译出来的 class 也没有泛型的,其实 Java 对于编译器而已,是没有所谓的泛型,都是强制类型转换过去的

    编写阶段
    public String saveOne(Map<String, Object> data) { ... }

    编译成 class 后
    public String saveOne(Map data) { ... }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2464 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 01:12 · PVG 09:12 · LAX 17:12 · JFK 20:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.