真是天道好轮回, Java 新特性:用 var 关键字,数据类型可以扔掉了? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shew5689
V2EX    Java

真是天道好轮回, Java 新特性:用 var 关键字,数据类型可以扔掉了?

  •  
  •   shew5689 2020-09-30 15:00:28 +08:00 8848 次点击
    这是一个创建于 1886 天前的主题,其中的信息可能已经有所发展或是发生改变。

    //JDK 10 中新增了 var 局部变量推断的功能:

    //场景一:定义字符串 //旧写法:

    String str = "Hello, Java.";

    //新写法:

    var s = "Hello, Java.";

    //PS:这里的旧写法指的是 JDK 10 之前的版本,而新写法指的是 JDK 10 以后(包含 JDK 10 )的版本

    //场景二:数值相加 //旧写法:

    int num1 = 111; double num2 = 555.666d; double num3 = num1 + num2; System.out.println(num3);

    //PS:当遇到不同类型相加时( int+ double )会发生数据类型向上转型,因此 num3 就会升级为 double 类型。

    //新写法:

    var n1 = 111L; var n2 = 555.666; var n3 = n1 + n2; System.out.println(n3);

    //场景三:集合 //旧写法:

    List<Object> list = new ArrayList<>(); list.add("Hello"); list.add("Java");

    //新写法:

    var list = new ArrayList<>(); list.add("Hello"); list.add("Java"); //......

    //Javascript:我慢慢靠近你,你慢慢靠近我,你中有我,我中有你,我特么谢谢你~

    90 条回复    2020-10-15 20:12:19 +08:00
    larisboy
        1
    larisboy  
       2020-09-30 15:10:40 +08:00
    还不如原来来的方便,出 BUG 都难找
    wupher
        2
    wupher  
       2020-09-30 15:23:31 +08:00
    类型推断,语言本身还是强类型的。

    虽然 JDK10 目前用的比较少,但是 18 年后主力代码已使用 Kotlin 编写:一样可以不显示声明类型,使用推断。从我个人开发经验来讲还好,并不会出 BUG 难找。
    titivillage
        3
    titivillage  
       2020-09-30 15:26:23 +08:00
    我选择 java,图的就是清晰的数据类型
    neptuno
        4
    neptuno  
       2020-09-30 15:28:20 +08:00   1
    只是语法糖吧,,底层还是强类型,可以选择不用呀
    mcluyu
        5
    mcluyu  
       2020-09-30 15:37:53 +08:00   3
    类型推断跟强弱类型并不冲突, 只是从显示静态类型变为隐式,跟 Javascript 的弱类型动态类型检查并不一样。
    seakingii
        6
    seakingii  
       2020-09-30 15:38:56 +08:00   1
    var 只是语法糖,或许,在查看源代码时不能一目了然的看清楚变量的类型,但对编译器来说,此变量的类型和显示定义是一模一样的。
    EscYezi
        7
    EscYezi  
       2020-09-30 15:42:44 +08:00 via iPhone
    还是感觉不太习惯,经常不能第一时间看出变量的类型。每行长度倒是变短了
    wysnylc
        8
    wysnylc  
       2020-09-30 15:43:16 +08:00
    类型推断≠弱类型
    class 里会变成实际类型
    ipwx
        9
    ipwx  
       2020-09-30 15:43:48 +08:00   19
    ... var 在 C#/Scala 里面都多少年了。连 C++ 都好多年前就实装 auto 关键字了。。。

    还有,这哪是什么轮回。JS 的 var 关键字有作用域的傻逼设计,而 Java 的 var 和 C++ 他们一样都只是语法糖,作用域和原来一样,根本不是一个东西好不好。要我说,Java 这波就是借鉴 C#,而不是借鉴 JS 。
    kraits
        10
    kraits  
       2020-09-30 15:49:22 +08:00 via Android
    好像 var 的使用也有很多限制,我还是喜欢写类型声明,虽然懒也不写 var
    Reficul
        11
    Reficul  
       2020-09-30 15:50:01 +08:00   10
    类型推导,本身语言还是强类型的,所以 IDE 和编译器一样能告诉你每个值的类型。

    每次看到 Java Boy 发言,就忍不住又想地图炮。Java Boy 是不是都在自己的世界里,本能地拒绝先进改变。
    glaucus
        12
    glaucus  
       2020-09-30 15:50:21 +08:00   1
    Kotlin 写多了觉得这种挺好的
    allan888
        13
    allan888  
       2020-09-30 15:51:50 +08:00 via Android   1
    说真的面对一个巨大的代码库我宁愿用旧的写法, 这样减少我读代码的心智负担。其实大公司一般一个人一星期写不了几行代码,读代码 vs 写代码时间可能超过 10:1.
    lyb11232345688
        14
    lyb11232345688  
       2020-09-30 15:53:41 +08:00
    第一次看到类型推断是在接触 golang 的时候,感觉挺好用的
    TarotVoyager
        15
    TarotVoyager  
       2020-09-30 15:54:01 +08:00   9
    dotnet: 北京申奥成功了
    allan888
        16
    allan888  
       2020-09-30 15:54:53 +08:00 via Android
    尤其是 code review 的时候我觉得这些省掉的部分都相当于某种程度的注释。
    还有一个情况是很多滥用的 Stream api 真的是非常难看看懂。。。
    shyling
        17
    shyling  
       2020-09-30 15:55:24 +08:00
    别的语言早就能用的东西还要讨论什么好用不好用。。。这是有多井底之蛙
    pkoukk
        18
    pkoukk  
       2020-09-30 15:56:42 +08:00
    这不就是编译器的类型推断嘛?保守估计 c#至少 5 年前就有了..
    cheng6563
        19
    cheng6563  
       2020-09-30 15:58:31 +08:00
    用 IDEA 一般都是 "new Object()" 然后按 Ctrl+Alt+V,就能前面自动打出" Objec objec = " 了,感觉 var 没啥用。
    echo1937
        20
    echo1937  
       2020-09-30 16:01:35 +08:00
    我看了日历,现在都 JDK15 了,怎么还在发 JDK10 特性的帖子。
    kuro1
        21
    kuro1  
       2020-09-30 16:04:09 +08:00
    golang
    a := "hellp"
    cmdOptionKana
        22
    cmdOptionKana  
       2020-09-30 16:04:15 +08:00
    @allan888 读代码 /code review 主要看逻辑吧,多数时间不需要管类型啊。而且多数情况下如果类型有错,IDE 会有提示。

    类型推导之所以能流行,就是因为实践中不需要那么 verbose 。
    tabris17
        23
    tabris17  
       2020-09-30 16:07:03 +08:00
    C#早八百年就实现的语法糖

    这只是类型推导,不是可变类型
    tabris17
        24
    tabris17  
       2020-09-30 16:10:22 +08:00
    @pkoukk 我去考证了一下,C#3.0 的特性,2007 年就有了
    majiaxin110
        25
    majiaxin110  
       2020-09-30 16:13:13 +08:00
    人家就是个语法糖
    tctc4869
        26
    tctc4869  
       2020-09-30 16:14:34 +08:00
    你才知道?
    allan888
        27
    allan888  
       2020-09-30 16:16:14 +08:00 via Android
    @cmdOptionKana 因为 review 基本都尽量希望在 github 上看完,实在不确定才 pull 下来看。
    理论上类型问题不大,但是比如你写一个 map 一开始就写好类型我就更好理解这个 map 怎么设计的也大概猜到后面会怎么用,Map 这些类型被玩出花的时候我感觉光靠眼睛看还是有点累。我主要想说如果一件事多花费写的时间,但是省下读的时间的话,长期看对大家都是非常非常值得的。
    lavvrence
        28
    lavvrence  
       2020-09-30 16:16:27 +08:00
    旧特性:类型推导。
    TarotVoyager
        29
    TarotVoyager  
       2020-09-30 16:16:39 +08:00
    Javaer 的没见识真的是笑料
    wysnylc
        30
    wysnylc  
       2020-09-30 16:18:12 +08:00
    @Reficul #11 眼里有偏见的人只会看到偏见
    la2la
        31
    la2la  
       2020-09-30 16:22:24 +08:00
    这个不是 scala 嘛
    superrichman
        32
    superrichman  
       2020-09-30 16:23:10 +08:00 via iPhone
    python:你啥时候把 var 也扔掉?
    MarioLuo
        33
    MarioLuo  
       2020-09-30 16:23:33 +08:00 via Android
    @wupher 学习了 2 天的 kotlin, 问个问题,老项目值不值得切换到 kotlin 了?,kotlin 确实解决了 java 开发中的日常痛点,不过目前看没有太大的吸引力去驱动老项目切换到 kotlin
    quan01994
        34
    quan01994  
       2020-09-30 16:25:46 +08:00
    不,
    java 的 var 在我看来还是有点不舒服,有可能我已经习惯了写类型。
    但是写 C#的时候通篇 var,都不会感到不舒服。。。
    dadachen1997
        35
    dadachen1997  
       2020-09-30 16:26:20 +08:00
    这是“新”特性吗,用了有两年多了。。。。
    tachikomachann
        36
    tachikomachann  
       2020-09-30 16:27:48 +08:00 via Android   1
    我觉得以后 idea 估计会跟进,在 var 定义的地方提示类型
    starcraft
        37
    starcraft  
       2020-09-30 16:34:36 +08:00
    显然是 C#那套 var 啊,关 js 什么事。
    chendy
        38
    chendy  
       2020-09-30 16:37:19 +08:00
    悄悄说一句,lombok 有个 var,甚至有 val
    但是还是用不惯,毕竟平时也不需要手打类型,都是 .var 出来的
    goodboy95
        39
    goodboy95  
       2020-09-30 16:38:59 +08:00
    @tachikomachann idea 到 2019.1 了都没更新自动提示 var 类型的功能,vscode java 插件倒是支持了
    sxfscool
        40
    sxfscool  
       2020-09-30 16:40:05 +08:00   1
    两个槽点:
    1.java10 就有的特性,很久之前就有了
    2.各位 javaer 的抱残守缺我是没想到的
    shew5689
        41
    shew5689  
    OP
       2020-09-30 16:42:42 +08:00
    我抖了一下机灵,没想到引来了这么多键盘侠~,有些童鞋说借鉴的是 C#, 从发布时间上面看,C# 比 ECMAScript 晚了 5 年~,搞不好 C#也是借鉴的 ECMAScript



    ECMAScript
    发行时间 1997 年
    型系 弱类型、
    ecma-international.org


    C# 1.0
    2002 年 1 月
    随 Visual Studio 2002 和 .NET Framework 1.0 发布
    InkStone
        42
    InkStone  
       2020-09-30 16:49:48 +08:00
    @shew5689 前面已经有人说过了,js (或者 es )的 var 跟 Java/C#/C++的根本不是一回事。

    你怎么不说它们都是借鉴 VB 的呢? dim a = 3; 不比 ES 早多了么。
    shew5689
        43
    shew5689  
    OP
       2020-09-30 16:51:45 +08:00
    @InkStone ECMAScript 中 var 也是作者设计的语法糖啊~
    yolee599
        44
    yolee599  
       2020-09-30 16:54:09 +08:00   1
    习惯了强类型的 C 语言,反而觉得 var 这种类型定义很没踏实感
    chocotan
        45
    chocotan  
       2020-09-30 16:54:42 +08:00
    已经 jdk15 了
    shew5689
        46
    shew5689  
    OP
       2020-09-30 16:57:23 +08:00
    @chocotan 大清的辫子还在你心中。
    shew5689
        47
    shew5689  
    OP
       2020-09-30 16:59:16 +08:00
    上面的部门键盘侠,就算 jdk15 了,jdk10+的新特性你们了解多少?
    gdtdpt
        48
    gdtdpt  
       2020-09-30 17:01:19 +08:00
    写过 switf 、ts 、js 、golang 之后每次写 Java 的时候都会觉得 Java 的变量声明实在是在嗦了,明明可以根据表达式推断变量类型非要在变量前面显式加上类型声明,有些类名字还贼长,虽然 idea 能提示,但是遇到命名相似的类一不小心选错了也很糟心。
    neptuno
        49
    neptuno  
       2020-09-30 17:02:39 +08:00
    @cheng6563 new Object().var 也会直接生成
    Oktfolio
        50
    Oktfolio  
       2020-09-30 17:04:08 +08:00
    @shew5689 jdk 11 正式发布就把 9 10 11 新特性完整过了一遍。12 13 14 15 语法上的新特性也都稍微看了看,等 Shenandoah + TLS 直接无脑上新版本。这都 0202 年了,还在说 var ......
    digitO
        51
    digitO  
       2020-09-30 17:04:42 +08:00
    java 转 kotlin 表示真香,java 的代码的确有些繁琐
    across
        52
    across  
       2020-09-30 17:06:54 +08:00
    都转去补习 C++吧,一个类型推导早讨论烂了
    wmwmajie
        53
    wmwmajie  
       2020-09-30 17:07:58 +08:00
    然后 java 就变成 PHP 了呗(手动滑鸡)
    namelosw
        54
    namelosw  
       2020-09-30 17:14:06 +08:00 via iPhone
    这种类似 C#的局部推导跟 TS 之类的全局推导用起来体验差很多. C#经常抽个带匿名类型的方法就要补半天签名.
    woostundy
        55
    woostundy  
       2020-09-30 17:15:25 +08:00   1
    @shew5689 #41 感人。C#的 var 和 js 的 var 除了都叫 var 还有啥关系?
    要说用这单词,1971 年的 Pascal 就有 var 了,要说类型推断 1991 年的 Python 更早。怎么扯也扯不到 js 上。
    wupher
        56
    wupher  
       2020-09-30 17:21:25 +08:00   1
    @MarioLuo 浅见,仅供参考。

    我是新项目使用 Kotlin,包括后端和 Android 。

    之前后端使用 Groovy,配合 GORM 以及 Spring 。使用 Kotlin 后强类型语言的好处是,编译阶段能解决 80%的问题。强类型语法检查很犀利。坏处也是有的,Kotlin 的强类型甚至体现在容器及模板类。会给 json 的动态转化带来一些问题:接口传输中的 “1”与 1,是完全不同的类型。你的对象类必须严格符合;而在 Groovy 中没有真正的类型,接口中的"1",你想解释成 String, int, Integer, Long 全看你心情。而接口这东西,又不仅仅靠你自己,也要看对方实现人员的实现和心情。

    与 Java 相比 Kotlin 的语法糖更多,且甜。(虽然可能不一定 Groovy 等动态类型那么甜)像修改、扩展类函数,动态生成函数及类,包况 FP,type alias,如果要封装 DDD 框架,也是很方便的。但是总体上,仍然是一种强类型语言。

    目前,Kotlin 在低层能带来其它加分,主要是 Coroutines 。但 ReactiveX 本身也很好用了。

    综上所述,我个人觉得新项目还是挺适合 Kotlin,旧项目如果是 Java 编写还是照旧吧,我目前也是如此。
    haleyao
        57
    haleyao  
       2020-09-30 17:21:37 +08:00
    连我这个对 PL 一无所知的人都知道类型推导,在较“新”的语言里面好像都是标配,比如 dart rust
    咋就还扯上 js,php 呢
    xxboy 我认为涉嫌语言歧视,我更愿意称为培训班 boy
    yazinnnn
        58
    yazinnnn  
       2020-09-30 17:24:27 +08:00
    不行,还不算好用

    A a = str -> { };

    var b = str -> { }; //无法推断类型:lambda 表达式需要显式目标类型
    shew5689
        59
    shew5689  
    OP
       2020-09-30 17:25:17 +08:00
    @haleyao 请问您是哪类 boy?
    shew5689
        60
    shew5689  
    OP
       2020-09-30 17:26:43 +08:00
    @haleyao 优越感这么强~ 谦虚一点不行~
    MarioLuo
        61
    MarioLuo  
       2020-09-30 17:28:04 +08:00 via Android
    @wupher 准备下个新项目试试 kotlin, 空检查很棒,避免了 Java 中的一些防御性代码
    wangwei1025
        62
    wangwei1025  
       2020-09-30 17:32:51 +08:00
    为什么不用 scala
    InkStone
        63
    InkStone  
       2020-09-30 17:36:43 +08:00   1
    @shew5689 es 里的 var 不是语法糖,我认为稍微有点编译器知识的人都能看出这一点……

    就像 dim a = 3 里的 dim 也不是语法糖一样。dim a as Integer = 3 能省略成 dim a = 3 才叫语法糖。

    js 里有 var,纯粹是因为这样实现编译器比较简单(对比不需要 var 的 python ),这是一个语法盐,故意让你写着难受的。
    shew5689
        64
    shew5689  
    OP
       2020-09-30 17:37:10 +08:00
    下班咯,祝楼上的老哥们,中秋国庆假期快乐~
    sxfscool
        65
    sxfscool  
       2020-09-30 17:39:05 +08:00   1
    楼主舌战群儒,
    IGJacklove
        66
    IGJacklove  
       2020-09-30 17:46:53 +08:00 via Android
    这个不是早就有了? JDK11 就有了吧,我记得都是两三年前的事了
    BoarBoar
        67
    BoarBoar  
       2020-09-30 18:25:51 +08:00
    这是语法糖吧,和 go 差不多,编译时就推断了类型
    比起 python 之类的动态类型根本是两回事
    Shook
        68
    Shook  
       2020-09-30 19:12:02 +08:00
    和 C#的有啥不一样?
    Cbdy
        69
    Cbdy  
       2020-09-30 19:46:23 +08:00
    村网通系列。。
    EminemW
        70
    EminemW  
       2020-09-30 20:26:39 +08:00
    我几年前就看过这个。。
    wolfie
        71
    wolfie  
       2020-09-30 22:13:46 +08:00
    前几层没看到嘲讽楼主的话,反复确认时间。
    Bromine0x23
        72
    Bromine0x23  
       2020-09-30 23:00:34 +08:00   1
    es 的 var 变量声明和静态语言的类型推导特性显然不是一回事,像
    ```
    var x = 1;
    x = "1";
    ```
    对类型推导来说不合法的,因为 var 表示的类型不是任意的,而需要根据赋值表达式推导出来的;一旦推导出来,所表示的类型就固定了。

    要翻源头的话,应该是某个函数式语言开始的,像 83 年的 Standard ML 就已经有这个特性了
    simpledwcom
        73
    simpledwcom  
       2020-09-30 23:51:55 +08:00
    没用的鸟功能,我就想要强类型的。。。
    aguesuka
        74
    aguesuka  
       2020-10-01 09:38:30 +08:00 via Android
    新特性 x
    不是贴别旧的特性 o
    aguesuka
        75
    aguesuka  
       2020-10-01 09:41:26 +08:00 via Android
    @tachikomachann 早就有了
    yiyi11
        76
    yiyi11  
       2020-10-01 10:13:42 +08:00 via Android
    new Object().var + tab 键 or enter 键,自动返回值类型补全。智能提示真是太棒啦。你说什么?我一直在用 idea 啊。
    xuanbg
        77
    xuanbg  
       2020-10-01 10:35:22 +08:00
    这个叫类型推断,不是没有数据类型好吧。var a = new String();变量 a 难道就不是 String 类型了?编译器能够从 new String()得到 a 的类型,不需要你特意指定 a 的类型而已。

    idea 有个插件,可以把类型隐藏掉,然后显示为 var……
    JB18CM
        78
    JB18CM  
       2020-10-01 11:04:00 +08:00
    标题党,无聊至极
    littlewing
        79
    littlewing  
       2020-10-01 13:40:46 +08:00
    强类型的语言搞这种东西没什么用,就像 py 一样
    liyhu
        80
    liyhu  
       2020-10-01 13:59:56 +08:00
    感觉是挺没用的,我也不喜欢这个语法糖
    love
        81
    love  
       2020-10-01 14:15:51 +08:00
    @littlewing 类型和强类型完全不是一回事。类型当然重要,你 py 的函数参数和返回个啥类型都不知道,还要看一遍代码实现,非常地不生产力
    ericgui
        82
    ericgui  
       2020-10-01 14:18:18 +08:00
    @seakingii 既然 compiler 层面都一样,不如直接显式声明数据类型,可读性还是很重要的
    tairan2006
        83
    tairan2006  
       2020-10-01 16:07:28 +08:00 via Android
    楼主有点蠢…js 那是语法糖?
    seakingii
        84
    seakingii  
       2020-10-01 17:01:25 +08:00 via Android
    @ericgui 你可以继续用老的显式完整的声明。我个人更喜欢 var 类型推断
    JerryCha
        85
    JerryCha  
       2020-10-01 17:58:51 +08:00
    Microsoft: 因为我们跑的和香港记者一样快,以至于大家看见 Java 的 var 还以为是从 JS 学来的。
    lxilu
        86
    lxilu  
       2020-10-01 21:58:50 +08:00
    @InkStone #42 VB 声明赋初值.Net 才有(非反驳)
    LokiSharp
        87
    LokiSharp  
       2020-10-01 23:26:17 +08:00 via iPhone
    感觉 Java 逐渐变成 C# 的形状了
    ijrou
        88
    ijrou  
       2020-10-02 00:50:29 +08:00
    早就听闻 Java 开始往 C#线路走了,果然没错。。。看来 java 还是。。。
    ipwx
        89
    ipwx  
       2020-10-02 10:44:18 +08:00
    @love 论生产力,Python 3.6+ 的 type annotation 已经很足够了。
    lxk11153
        90
    lxk11153  
       2020-10-15 20:12:19 +08:00
    'var' is not allowed in a compound declaration
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2612 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 03:08 PVG 11:08 LAX 19:08 JFK 22:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86