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

关于 Java 很啰嗦的问题

  •  3
     
  •   Joker123456789 · 2022-05-12 12:19:17 +08:00 · 20838 次点击
    这是一个创建于 934 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我先声明啊,我不是来吹捧 java 的,我只是想说一个事实,编程语言 没有谁绝对的碾压谁,真遇到了实际业务需求,写出来的代码量绝对是半斤八两。

    我希望大家 在 吐槽一门语言的时候,可以理性一点,不要瞎喷。这篇文章的用意就在于此。

    还有一点,我用 go 来比较,是因为 go 擅长的场景,跟 java 有一定的重叠,有很多公司都用 go 开发 web 。绝对没有对 go 不敬的意思。

    首先目录问题

    image.png

    总结下来,从工作量的角度来看,就是多了一个倒置的域名而已,而且只需要花建一层目录的时间,并且这个倒置的域名 是有他的意义在里面的,你们可以把他看做是这个

    // go 语言里的 import ,前面也有一个域名+项目名 来确定唯一性,包名里的倒置域名就是起这个作用的
    import "github.com/scan-util/xxx/xxx"
    

    还有很重要的一点,你们喷来喷去的那些多余的目录结构,在我们的观念里 根本就不存在,因为从来没有手工去创建过,要不是你们来吐槽,我们还真想不到这一点。

    不是因为 习惯了,而是真的从来没有为他们花过 5 秒钟以上的时间。有的连一毫秒都没花过。

    方法语法

    go

    func BytesToString(val []byte) string
    

    java

    public String BytesToString(byte[] val)
    

    我真没看出来多了什么东西

    定义变量

    go

    name := "张三";
    
    var map = make(map[string]interface{})
    var array = make(string[], 10);
    

    java

    String name = "张三";
    
    Map<String, Object> map = new HashMap<>();
    String[] array = new String[10];
    
    

    好像多了点东西,又好像没多什么。

    循环

    go

    for(i:=0;i<100;i++){
    
    }
    
    for(i<100){
    
    }
    

    java

    for(int i=0;i<100;i++){
    
    }
    
    while(i<100){
    
    }
    

    确实多了几个字母。

    创建类

    go

    我知道这叫结构体,跟类是两码事,但是 go 就是用它来兼容 oop 的,所以我只能用它来举例子,因为没有其他语法可以实现 oop 了

    type DemoParam struct {
        name string
    }
    
    func (demoParam *DemoParam) FormValues(key string) []string {
    }
    

    java

    class DemoParam {
        public String name;
        
        public String[] FormValues(String key){
            
        }
    }
    

    字数上相差多少,我是懒得数了,但是你们真的不觉得 java 的结构更清晰吗? 其他的继承,多态 我就不拿出来说了,go 基本上是 用的 c 的编程思想,oop 只是个兼容, 所以用 java 来跟他比 oop 没什么可比性。因为是两个方向。

    异常处理

    go

    
    func testFunction(paramStr string) (string, error) {
        if xxx {
            return Errors.New("xxxx");
        }
    }
    
    paramStr, err := testFunction("ok")                              
    if err != nil {                           
        log.Println(err.Error())                           
    }
    

    java

    public String testFunction(String paramStr){
        if (xxx) {
            throw new Execption("xxx");
        }
    }
    
    try {
        String paramStr = testFunction("ok");
    } catch(Execption e){
        log.Println(e.getMessage); 
    }
    

    这个看起来 go 好像 舒服一点,但是,实际场景下 go 经常是这种姿势

    paramStr, err := testFunction("ok")                              
    if err != nil {                           
        log.Println(err.Error())                           
    }
    
    paramStr, err := testFunction2("ok")                              
    if err != nil {                           
        log.Println(err.Error())                           
    }
    
    paramStr, err := testFunction3("ok")                              
    if err != nil {                           
        log.Println(err.Error())                           
    }
    

    而 java 还是只需要这样

    try {
        String paramStr = testFunction("ok");
        String paramStr = testFunction2("ok");
        String paramStr = testFunction3("ok");
    } catch(Execption e){
        log.Println(e.getMessage); 
    }
    

    并且这是 经过人为判断后,返回的错误提示,如果是意外的异常呢? go 里面叫 panic ,java 只要用 try catch 包住了 就可以捕获,但是 go 需要用 defer ,而且一旦抛出异常就意味着这个函数结束了,你如果想在出异常后,处理一下 然后继续往下走,go 会非常的麻烦。

    拆箱

    go

    // 如果有一个 interface{} 类型的变量 a ,想转成 int
    // 你必须明确的知道,他装箱前就是 int ,不然根本没法拆,必须做一下类型判断。
    // 我之前在写框架的时候 就被折磨的够呛,一大堆不必要的 if
    

    java

    // 不管装箱前是什么,只要他的值是一个整数
    // 无论是 1 , 还是 "1", 都可以这么转
    Integer aInt = Integer.parseInteger(a.toString());
    
    // 也可以直接拆成 String
    a.toString();
    

    如果你们还不服,那很好办,

    你们出一个需求给我,我用 java ,你们用 go ,nodejs ,python ,php 随便什么语言,最后来比比 谁的代码少一些。 我敢说,绝对半斤八两,不可能有谁碾压谁的。

    而且还有一定的概率,java 在 丰富的生态+强大官方库的 加持下,可以更快完成。

    第 1 条附言  ·  2022-05-12 13:14:21 +08:00
    补充一点,给我出题的前提是,你们带着自己的代码过来。并说清楚需求
    257 条回复    2022-11-14 13:32:01 +08:00
    1  2  3  
    clownpiece
        101
    clownpiece  
       2022-05-12 14:52:09 +08:00
    @lisongeee 那就这样呗,假设项目里有 100 个类都是这样 setter 里有通知变更逻辑的,java 和 kotlin 分别按各自的写法写好了,内部也是正常的通过 setter 修改。 现在新来了一个需求 也要新增 100 个类(这些类的名字和上面 100 个几乎一样,很容易混淆),也是有通知变更逻辑,但是他们都需要有内部修改字段不触发变更的逻辑。

    那么 java 和 kotlin 来比较一下大家代码的 diff 量?记得要考虑之后的维护
    wolfie
        102
    wolfie  
       2022-05-12 14:52:25 +08:00
    @lisongeee
    原来你不是不看上下文,是看不懂上下文。
    怪不得能说出以字符串多少评价语言啰嗦程度这种话。
    AoEiuV020CN
        103
    AoEiuV020CN  
       2022-05-12 14:52:52 +08:00
    很明显你是把第三库封装起来的行数给无视了,
    第三方封装了一千行,你只要一行就能调用,对你来说 java 只要一行就能完成工作,简洁,不啰嗦,
    但别人会看到这啰嗦的一千行代码,
    lisongeee
        104
    lisongeee  
       2022-05-12 14:54:52 +08:00
    @silentsky 那你是否承认 kotlin 语法产生的代码量平均少于 java ?,另外我不应该拿 kotlin 碰瓷高贵的 java 行了吧
    Leviathann
        105
    Leviathann  
       2022-05-12 14:55:39 +08:00
    @Buges 快排的精髓在于各种优化,而不是这个基本思想,不然的话干嘛不用归并,稳定且上界低
    Kaiv2
        106
    Kaiv2  
       2022-05-12 14:56:54 +08:00
    在 Java 8 之前确实是有点费劲。
    场景: 用户选择不同支付方式付款

    interface IUserService {
    User find();
    }

    class UserServiceImpl {
    User find() {
    }
    }


    interface IOrderService {
    void pay();
    }
    tomolo
        107
    tomolo  
       2022-05-12 15:01:36 +08:00
    一门语言用成死忠,争着争那的,只能说技术视野太狭窄了
    lisongeee
        108
    lisongeee  
       2022-05-12 15:03:55 +08:00
    @clownpiece

    https://stackoverflow.com/questions/61459289/how-to-skip-defined-getters-or-setters-in-kotlin

    另外人家题主明确说明了《最后来比比 谁的代码少一些。 我敢说,绝对半斤八两,不可能有谁碾压谁的。》

    佛了,我说了这么多优点,你是一个都不看呐,光顾着鸡蛋里挑骨头了是吧

    和你这种人还有什么讨论的必要呢,你是对的,我是错的,谢谢
    Oktfolio
        109
    Oktfolio  
       2022-05-12 15:05:33 +08:00
    @lisongeee Kotlin 本来就是解决 Java 甜度不够的问题的,OP 很明细不是来杠 Kotlin 的。Kotlin 对我来说存在 Int 兼容,没有无参构造,Data Class 类和成员是 Final 且没法用注解的问题,虽然可以用 noargs 和 allopen 解决,但总觉得不优雅,所以写 Kotlin ,我依旧会用 Java 来写数据实体类。
    fgwmlhdkkkw
        110
    fgwmlhdkkkw  
       2022-05-12 15:11:09 +08:00
    NIO
    lisongeee
        111
    lisongeee  
       2022-05-12 15:11:56 +08:00   ❤️ 1
    我发现某些单一语言的程序员都很固步自封,不肯接受新事物,我现在正式承认我是个傻逼,别来和我讨论了,我承认 java 在语法和生态都是最牛逼的语言,任何一门语言和它比都是垃圾,在它的光芒下都暗淡无光。用 java 的人的生活是完美的,只用 java 的人保持了他对 java 的忠贞,我多么想给这些里面的某些人发一个贞节牌坊。此贴终结,java 完胜。
    lisongeee
        112
    lisongeee  
       2022-05-12 15:12:34 +08:00
    @Oktfolio 是的,你是对的,我非常赞同你的观点
    lisongeee
        113
    lisongeee  
       2022-05-12 15:16:50 +08:00   ❤️ 1
    @xiangyuecn

    《 js 这样写够简洁了吧:
    (((json.obj1||{}).obj2||{}).obj3||{}).abc 》

    js 其实可以这样写,得益于 js 有 babel 的存在,可以把高版本语法糖转换为低版本语法

    json.obj1?.obj2?.obj3?.abc ,

    如果你想给一个缺省值,还可以 json.obj1?.obj2?.obj3?.abc ?? defaultValue
    ychost
        114
    ychost  
       2022-05-12 15:18:22 +08:00
    @Alexliu 你这个还真的很好解决,有 JSONPath ,无视空指针,
    JSONObject origin = JSONObject.parseObject("...");
    boolean isEqual = Objects.equals(JSONPath.eval(origin,"$.data.nation"),"印度尼西亚");
    yannxia
        115
    yannxia  
       2022-05-12 15:18:28 +08:00
    @timpaik 因为 go mod 只是一个包管理 ··· Gradle 是一个 Build System ··· 不太好比
    jsdi
        116
    jsdi  
       2022-05-12 15:18:45 +08:00
    一看到这种帖子就知道肯定有人要吵起来😐
    fredli
        117
    fredli  
       2022-05-12 15:19:00 +08:00
    还不用函数式,我认为就是落伍了,swift kotlin flutter...
    zmal
        118
    zmal  
       2022-05-12 15:20:40 +08:00
    转自邓草原大佬的说法:

    我为什么从 Scala 转回 Java 。1 、Java 已经吸收和实现了大部分类 Scala 的语法,而且还在继续; 2 、Java 的语法虽然没有 Scala 精炼但也更严格些 (也就是没那么灵活),但有成熟 IDE 的帮助,写起来也不慢和少错; 3 、能招到更多的程序员。最后,现在的 Java 已经足够好了,成为各种因素下最均衡的。 ​
    Kaiv2
        119
    Kaiv2  
       2022-05-12 15:21:55 +08:00
    @Kaiv2 想表达多继承没写完就按了下 tab 空格 发出去了 😂
    yannxia
        120
    yannxia  
       2022-05-12 15:22:52 +08:00
    @lisongeee 这就是一个月经帖,部分 Java 爱好者 和 Go 爱好者互喷,然后有个轴的人来了开战了,这事情本质上没啥意义,毕竟如果脱糖了,大家没啥区别,爱用啥用啥呗。比较烦那些总是来挑事情的人
    oneisall8955
        121
    oneisall8955  
       2022-05-12 15:26:03 +08:00 via Android
    天天吵天天吵,后端娱乐圈?
    zmal
        122
    zmal  
       2022-05-12 15:26:09 +08:00
    即使新出的语言比发展了几十年的语言更优秀一些也很正常,世界在进步嘛。

    不过语法糖这个东西,并不是越多越香。开发一时爽,维护火葬场。要不要加糖是一种取舍。
    storyxc
        123
    storyxc  
       2022-05-12 15:26:34 +08:00
    此贴有望热榜 top1
    lisongeee
        124
    lisongeee  
       2022-05-12 15:26:44 +08:00
    @Oktfolio

    《 Data Class 类和成员是 Final 且没法用注解的问题》


    1.Data Class 类和成员是 Final 这我知道,但是 data class 只是自动重写了一些方法而已,想继承不用就行了

    2.没法用注解的问题 dataclass 不能用注解吗?,我现在就是一直在用啊

    这有个例子 https://developer.android.google.cn/training/data-storage/room?hl=zh-cn#data-entity
    yaott2020
        125
    yaott2020  
       2022-05-12 15:27:16 +08:00 via Android   ❤️ 1
    外个楼,我不用 java 而用 golang 的原因只是因为需要安装 java 环境才能运行 java 代码,golang 编译出来就是二进制文件
    fredli
        126
    fredli  
       2022-05-12 15:33:11 +08:00
    userList.forEach {user.location = "sh"}
    .filter {user.age > 50}
    .map {user.id}

    请用 Java 翻译一下
    J2ephyr
        127
    J2ephyr  
       2022-05-12 15:35:44 +08:00
    来说一下关于我的瓜吧。1.首先谢谢大家对这件事情的关心。我事先根本没有想到会这样既然已经出这件事情了,那我不如直接讲清楚吧。也不是博得大家的同情什么的,只是回应一下。2.那人所发出来的聊天记录、照片、视频、甚至那些亲昵称呼都是真的,无一造假。可我从未将这些东西流传在任何网络平台上面,至于那个人是怎么有的,我也不清楚。3.虽然这事出了,但我没有不尊重任何人,我不认为我有错,所以我不会认错。4.最后,想知道到底发生了什么的,转我 88 肯德基疯狂星期四,我把故事从头到尾给你编一遍
    libook
        128
    libook  
       2022-05-12 15:39:29 +08:00   ❤️ 1
    我不参与,我就吃瓜,另外可以考虑开个 git repo ,每种需求每种技术栈的实现方案可以 pr ,然后收集起来。
    Leviathann
        129
    Leviathann  
       2022-05-12 15:40:24 +08:00
    @fredli
    第一个应该是 onEach
    java 没有 eager 的集合函数式操作 只能跟 sequence 一样头加个 stream 尾加个 toList()
    Leviathann
        130
    Leviathann  
       2022-05-12 15:41:55 +08:00
    @fredli 看错了 好像不是 kotlin 无视第一句吧
    0312birdzhang
        131
    0312birdzhang  
       2022-05-12 15:44:00 +08:00   ❤️ 1
    @frisktale 1 行

    Microsoft Windows [版本 10.0.22000.675]
    (c) Microsoft Corporation 。保留所有权利。

    F:\Program Files\Java\jdk-11.0.2\bin>.\jshell.exe
    | 欢迎使用 JShell -- 版本 11.0.2
    | 要大致了解该版本, 请键入: /help intro

    jshell> System.out.println("Hello World");
    Hello World

    jshell>
    Oktfolio
        132
    Oktfolio  
       2022-05-12 15:48:36 +08:00
    @lisongeee 那可能是 Java record 用不了注解?可能记混了。
    LeegoYih
        133
    LeegoYih  
       2022-05-12 16:04:06 +08:00   ❤️ 2
    @fredli

    userList.stream()
    .peek(u -> u.setLocation("sh"))
    .filter(u -> u.getAge() > 50)
    .map(User::getId)
    .toList();
    oneisall8955
        134
    oneisall8955  
       2022-05-12 16:07:45 +08:00
    @Alexliu #16

    @aragakiyuii #65

    @ychost #114

    仅仅 Jackson 也可以,性能未知,at 这个 api ,路径写法用 /xxx 开头,不像 JSONPath 的 $.xxx 好看吧

    ![]( https://cdn.liuzhicong.cn/img/20220512160406.png)
    justin2018
        135
    justin2018  
       2022-05-12 16:10:31 +08:00   ❤️ 1
    学了 2 个月的 Java 喜欢这种“啰嗦”的语言

    写前端 感觉“累” 可能我是菜鸡~~ 在逃避它~~~ o(╥﹏╥)o
    sky857412
        136
    sky857412  
       2022-05-12 16:11:10 +08:00
    @frisktale 伪需求
    yohole
        137
    yohole  
       2022-05-12 16:13:35 +08:00   ❤️ 4
    为楼主这种实践出真知的精神点赞,看到太多人贬低或者批判一个语言,多数都是停留在嘴炮,但是一旦到了上代码和需求的,都是不见人,不管怎样,这种精神和有理有据的回复点赞
    zzl22100048
        138
    zzl22100048  
       2022-05-12 16:17:34 +08:00
    @xiangyuecn json?.obj1?.obj2?.obj3 js 可以这样取,java 也可以用 optional 取
    sky857412
        139
    sky857412  
       2022-05-12 16:17:51 +08:00
    @lisongeee 无语了,封装性为什么不能违反?这只是一个中规范建议,明明可以简单解决,非要加个变量,然后再去维护一个变量的值?
    cnbatch
        140
    cnbatch  
       2022-05-12 16:18:01 +08:00
    @LotusChuan 不止语言宗教战争,还有框架宗教战争、IDE 宗教战争、操作系统宗教战争、许可证宗教战争。

    v 站稍微好一点,只是用户自发聊起来。

    某个 O 开头的开源资讯站(同时也是国内 git 托管公司)那边就不一样了,是由内部员工亲自发起这类宗教大战,不止发布开源软件新闻、行业新闻时会有意无意地这样做,甚至会以编辑部的名义亲自撰写这类大战文章,生怕没人吵架带不来流量。我原本打算单独发贴说 oschina 的事情的,结果刚发出来没多久就被一个疑似 o 站的员工 at 了下站长,要站长转水。于是我索性自己移到“水”算了,免得以后被人搞针对。接下来我特意搜了下,原来 o 站在这里有专门的官方号,不知道是不是相互有合作,所以不让说。
    luqingliang
        141
    luqingliang  
       2022-05-12 16:20:26 +08:00
    兄弟们,冲!
    lisongeee
        142
    lisongeee  
       2022-05-12 16:24:16 +08:00
    @sky857412 建议你去 jetbrains 的社区问这个问题
    Nicklove
        143
    Nicklove  
       2022-05-12 16:28:30 +08:00
    你有运行时
    aliensb
        144
    aliensb  
       2022-05-12 16:30:21 +08:00
    接 OP 的代码说一下

    paramStr, err := testFunction("ok")
    if err != nil {
    log.Println(err.Error())
    }

    paramStr, err := testFunction2("ok")
    if err != nil {
    log.Println(err.Error())
    }

    paramStr, err := testFunction3("ok")
    if err != nil {
    log.Println(err.Error())
    }
    而 java 还是只需要这样

    try {
    String paramStr = testFunction("ok");
    String paramStr = testFunction2("ok");
    String paramStr = testFunction3("ok");
    } catch(Execption e){
    log.Println(e.getMessage);
    }

    这里的两个语言的代码执行情况还不一样,go 会一直执行下去,但是 java 中任意一个 function 异常了就会直接走到 catch 块中去了
    yazinnnn
        145
    yazinnnn  
       2022-05-12 16:31:12 +08:00
    能不能多回一些建设性的贴子....
    sky857412
        146
    sky857412  
       2022-05-12 16:41:58 +08:00   ❤️ 1
    居然有些菜逼踩 spring ,至少围绕 spring 这个生态,大家玩的很开心。vertx 就从来没人吵,vertx 性能比 spring 好,不还是用的人很少。
    sky857412
        147
    sky857412  
       2022-05-12 16:47:39 +08:00
    @lisongeee jetbrains 限制了再 setter 方法中写通知了?
    封装性是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。这个跟 setter 方法有什么关系?
    sciel
        148
    sciel  
       2022-05-12 16:48:20 +08:00
    我想看一下,java ,nodejs ,python ,php 实现下面的这个方法,可以吗 ^_^
    ```
    // 获取接口数据 接口超时 3 秒,超时后重试 5 次 , 成功则获取返回状态为 0 和 1 时的数据
    /* 接口返回数据格式
    {
    "code":0 // -1 失败 0 成功 1 预警
    "msg":""
    "data":{}
    }
    */

    func (s *rss) fetchData(ctx context.Context, url string) (*gjson.Json, error) {
    num, max := 0, 5
    retry:
    d, err := gclient.New().Timeout(time.Second*3).Get(ctx, url)
    if err != nil {
    num++
    if num > max {
    return nil, errors.New(fmt.Sprintf("获取数据失败,已重试%d 次,请稍后重试", max))
    }
    glog.Infof(ctx, "获取失败,重试中...%d", num)
    goto retry
    }
    json, err := gjson.DecodeToJson(d.ReadAll())
    if err != nil {
    return nil, err
    }
    switch json.Get("code").Int() {
    case 0, 1:
    return json.GetJson("data"), nil
    default:
    return nil, errors.New("获取数据失败,请稍后重试")
    }
    }
    ```
    anonydmer
        149
    anonydmer  
       2022-05-12 16:49:28 +08:00
    不知道我一个工作中既用 java 也用 go 的进来凑什么热闹
    Jwyt
        150
    Jwyt  
       2022-05-12 16:53:29 +08:00
    @sciel 这不就是一个请求重试么,是有什么特别的我没发现吗?手写的话一个 while 就好了阿
    lisongeee
        151
    lisongeee  
       2022-05-12 16:56:35 +08:00
    @sky857412 是的,你是对的
    sciel
        152
    sciel  
       2022-05-12 16:58:41 +08:00
    @Jwyt 我想体现一下 goto 。。失败
    122006
        153
    122006  
       2022-05-12 17:01:24 +08:00
    来试试我的 java 语法糖,模板字符串,https://github.com/122006/Zircon
    Jwyt
        154
    Jwyt  
       2022-05-12 17:02:15 +08:00
    @sciel 好吧,但是这个需求确实是一个 while 就 ok 的了
    Leviathann
        155
    Leviathann  
       2022-05-12 17:03:38 +08:00
    @sciel 这不就是 labeled break
    Suntz
        156
    Suntz  
       2022-05-12 17:09:15 +08:00   ❤️ 1
    切莫眼高手低踩一捧一,编程语言本质上就是一门工具,程序员生来就是解决需求的,任何技术都不分高低贵贱,任何一门技术都有他所适合的应用场景
    ychost
        157
    ychost  
       2022-05-12 17:12:46 +08:00
    @oneisall8955 FastJSON 的 JSONPath https://github.com/alibaba/fastjson/wiki/JSONPath
    当然如果了解 Groovy 4.0 目前也有 GINQ 了(对比 C# 的 Linq )
    danhahaha
        158
    danhahaha  
       2022-05-12 17:15:47 +08:00
    得了吧,大部分人还在乎多写几个字符?不就是 ctrl+c, ctrl+v 么
    茴香的茴怎么写最快?来辩论下?
    chenyu0532
        159
    chenyu0532  
       2022-05-12 17:16:55 +08:00
    本来以为前端是娱乐圈,后端也要慢慢向前端发展么。

    麻烦你们尊重下楼主好不好,不服的跟楼主 battle 啊,piapia 打他脸啊,开新帖子啊。
    Uplay
        160
    Uplay  
       2022-05-12 17:17:09 +08:00
    摸鱼时最开心看到这种东东了,悄悄说一句 kotlin 好爽
    122006
        161
    122006  
       2022-05-12 17:23:20 +08:00   ❤️ 1
    快下班了摸摸鱼,来试试我的 java 语法糖
    [模板字符串],0 侵入接入已有项目,和其他语言的模板字符串比更加强大。
    java 有什么不好的地方,与其怨天尤人,不如自己写语法糖接入就行了啊,多大点事。
    原生是不支持模板字符串的,动辄一堆加号和 format 看起来就很乱,这个库引入了模板字符串的写法。
    项目地址:github.com/122006/Zircon
    欢迎 star
    crazycarry
        162
    crazycarry  
       2022-05-12 17:26:19 +08:00
    这么菜怎么有脸问这个问题。
    Chinsung
        163
    Chinsung  
       2022-05-12 17:33:19 +08:00
    其实一般用 Kotlin 的真没啥好喷 Java 的,我把所有你觉得复杂的语法写法功能写一个类只提供一个函数做到,不也简洁了? Kotlin 就是 Java 的糖衣。
    其实我发现拿语法喷 Java 的,写 Go 的很多
    另外,都 21 世纪了,有 IDE 的辅助,除非某个语言对某个模式或者某种实现达到了毁灭性的不支持,否则你按下回车出来的是 10 个字符还有 20 个字符,差距很大吗?
    clf
        164
    clf  
       2022-05-12 17:56:11 +08:00
    我现在是 kotlin 和 java 都用,当然主要是开发 Web 或者 IDEA 插件 或者 android app 。

    偶尔还写前端的 js/ts 。

    写小工具一般用 python 。

    像 go 、R 、php 等等都有涉猎,合适的场景选择合适的语言就行了,这是程序员应该有的基本能力。
    Nazz
        165
    Nazz  
       2022-05-12 18:01:44 +08:00
    java 没有匿名函数, 没有裸函数
    fanxasy
        166
    fanxasy  
       2022-05-12 18:10:57 +08:00
    塔塔开!(偷偷顶一顶 kotlin 和 c#)
    cmdOptionKana
        167
    cmdOptionKana  
       2022-05-12 18:25:20 +08:00
    Go 把一个函数直接当作参数喂给另一个函数(即 higher order function )是很常见的操作,这在 Java 里一般怎么做?
    Mexion
        168
    Mexion  
       2022-05-12 18:31:41 +08:00
    @xiangyuecn js 读取不是这样吗? json?.obj1?.obj2?.obj3?.abc
    Mexion
        169
    Mexion  
       2022-05-12 18:41:32 +08:00
    @sciel goto 这东西难道 node 用 label 做不到吗:)
    Mexion
        170
    Mexion  
       2022-05-12 18:43:17 +08:00
    @Chinsung 写 Go 的哪来的脸喷 Java 的语法,Go 的语法烂的很
    hhjswf
        171
    hhjswf  
       2022-05-12 18:47:29 +08:00
    @Nazz 什么叫 Java 没有匿名函数。。。哪个版本的
    micean
        172
    micean  
       2022-05-12 18:47:51 +08:00
    java 的生命力真强,已经没有人为 php 争吵了
    ojh
        173
    ojh  
       2022-05-12 18:55:24 +08:00
    @cmdOptionKana 在 Java 叫函数式接口,简化一下就是 lamda 了,顺便问下 Go 有尾随闭包吗,多尾随闭包呢(开玩笑)
    spicecch
        174
    spicecch  
       2022-05-12 19:03:59 +08:00
    莫多莫多!
    TAFMT
        175
    TAFMT  
       2022-05-12 19:04:47 +08:00
    来吃个瓜👀
    james122333
        176
    james122333  
       2022-05-12 19:22:54 +08:00
    @Joker123456789

    "字数上相差多少,我是懒得数了,但是你们真的不觉得 java 的结构更清晰吗? 其他的继承,多态 我就不拿出来说了,go 基本上是 用的 c 的编程思想,oop 只是个兼容, 所以用 java 来跟他比 oop 没什么可比性。因为是两个方向。"
    => 没觉得比较清晰 java 是 field 与 method 混在一起 东西多了会很乱 go 的反而清晰多了

    "但是 go 需要用 defer ,而且一旦抛出异常就意味着这个函数结束了,你如果想在出异常后,处理一下 然后继续往下走,go 会非常的麻烦。"
    => 你封装一个函数以后都用那个函数 以结果来讲一模一样 封装也不麻烦 而且还不用注意哪些要抛出哪些不用

    "// 不管装箱前是什么,只要他的值是一个整数 // 无论是 1 , 还是 "1", 都可以这么转"
    => 你用了 Integer.parseInt 然而你 go 自己写个函数里面 switch type 判断是更佳的 如果你确定就是 int 那直接转就可以
    xsen
        177
    xsen  
       2022-05-12 19:25:02 +08:00   ❤️ 2
    如何把一段简单的代码变复杂?
    https://www.zhihu.com/question/277243683/answer/393676961

    换个人话的说话就是,Java 为什么越来越啰嗦、越来越重——过度设计
    ——————————————————————————————

    作者:Damon DanceForMe
    链接: https://www.zhihu.com/question/277243683/answer/393676961
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    这问题你应该去问企业级 Java 架构师。就比如 print 一句 hello world 吧。main 函数里 print 一下?太面向过程,太 low 了。得封装一个类。叫 Printer. Printer 有个成员方法,叫 print 。但是!光一个类太 low 了,以后要是有不同的实现怎么办?所以得加一个接口。PrinterInterface 。但是! interface 是没有实现的,还是要有默认实现才行。所以得加个虚拟类,AbstractPrinter 实现 PrinterInterface ,然后 Printer 继承 AbstractPrinter 。但是!你有了那么一套,该怎么创建实例呢?直接 new Printer()?太 low 了,那叫实现依赖。肯定不行的,所以要搞一个工厂类,PrinterFactory ,PrinterFactory 用 PrinterInterface 返回实例,这样就隐藏了实现细节了。但是! PrinterFactory 本身也是实现类啊,太 low 了,所以得有 PrinterFactoryInterface, AbstractPrinterFactory. 而且在 PrinterFactory 里面该怎么写呢?直接 new Printer()? 太 low 了。还是实现依赖。最后,你要把这一堆玩意在代码里组装起来,也太难看了,各种 new 实现类。太 low !好在我们有个高级玩意,叫依赖注入!把程序对象结构全写到配置文件里面。这一套当然是不能自己造轮子的。配置 Spring 吧。搞了那么多 lib ,靠命令行或者 IDE 的项目管理肯定不够啊,得有依赖管理。Maven 啊 Gradle 啊使劲上。最最后,要 print 的东西怎么传给程序呢?硬编码?命令行传参数?太 low !当然得写在 XML 里头。光是 XML 当然还不够企业级,再加上 DTD 验证吧。然后就涉及到了 XML 解析的问题了。代码里直接操起 parser 吗?太 low! 当然要写个 parser 的包装类,interface, abstract class, implementation class, factory class 再来一套。毕竟,不能依赖实现啊,以后我要是换 parser 了怎么办。所以最后是成品是一堆配置文件,一堆 jar ,compile 出来的程序 200MB 。IDE 得装上 300 个插件,打开项目硬盘响老半天吃掉 2GB 内存,然后一堆插件弹提示要求升级。哦对了,在这一切发生之前,还得画 UML 图呢。三年后项目完工了,部署到客户的服务器上一跑,立马崩溃,一地的 stack trace 。原来客户服务器上用的是 JDK 5 而新项目需要 JDK 6. 然后问客户你们不能升级吗,答案是不行,因为另外一个企业级开发组给做的企业级解决方案只支持 JDK 5 。接着客户把你们的架构师臭骂了一顿,你搞了那么多设计就没有想过可能会换 JDK 吗?
    james122333
        178
    james122333  
       2022-05-12 19:48:57 +08:00
    @Macolor21

    因为类型所以全代码都很清晰?... 类型清晰了但代码乱在其他也没用... 而且 go 也是类型
    go 主要是比较容易强迫你写出比较工整的代码 外加语法简单 这样来讲就是更清晰
    我都写 java 但很多 javaer 其实就习惯了 满足于现状 不能意识到这堆山堆的有多高 如果没有网路资源 又要花多少时间除错...
    ychost
        179
    ychost  
       2022-05-12 20:07:32 +08:00
    @sciel java 也有 label 语法不过只能用在 break 不能 goto (有语法,没实现),goto 设计上并不优雅,建议用闭包好点
    sola97
        180
    sola97  
       2022-05-12 20:17:14 +08:00 via Android
    @Alexliu 直接找个网站 json 转 java pojo ,类就建好了
    lbp0200
        182
    lbp0200  
       2022-05-12 20:29:27 +08:00
    启动 50 万个工作者 worker ,也不用干什么,内存不爆就可以
    go 和 kotlin 很简单,Python 比较麻烦,Java 看水平

    func TestName2(t *testing.T) {
    for i := 0; i < 500000; i++ {
    go func(index int) {
    fmt.Println(index)
    for {
    time.Sleep(time.Second)
    }
    }(i)
    }
    select {}
    }
    bybyte
        183
    bybyte  
       2022-05-12 20:31:34 +08:00
    吃瓜,留个位置
    eote
        184
    eote  
       2022-05-12 20:51:27 +08:00
    @lbp0200

    void testName2() {
    IntStream.range(0, 50000).forEach(i -> new Thread(() -> {
    System.out.println(i);
    for (;;) {
    try {
    Thread.sleep(1);
    } catch (InterruptedException ignored) {}
    }
    }));
    }
    eote
        185
    eote  
       2022-05-12 20:52:11 +08:00
    @lbp0200 更正

    void testName2() {
    IntStream.range(0, 50000).forEach(i -> new Thread(() -> {
    System.out.println(i);
    for (;;) {
    try {
    Thread.sleep(1);
    } catch (InterruptedException ignored) {}
    }
    }).start());
    }
    cocong
        186
    cocong  
       2022-05-12 21:01:42 +08:00   ❤️ 2
    代码写得再漂亮,也无法摸出业务的复杂性。

    在复杂业务逻辑下,哪种语言写出来的代码都一样。

    与其纠结代码优雅,不如思考如何简化业务。
    Seanfuck
        187
    Seanfuck  
       2022-05-12 21:01:43 +08:00
    居然还有想挑战 php 的,php 不用写一个 import 或 class 或 function 就能快速达成目标,而且还不用开笨重编辑器,不用编译。
    ikas
        188
    ikas  
       2022-05-12 21:26:06 +08:00
    贴一个目前在用的 java 脚本..更新 mc 服务器的 ipv6 地址到 hosts
    利用 git 推送 ipv6 地址到 github,然后其它机器同步写入 host

    UpdateIp.java
    -----------------------
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;

    public class UpdateIp {
    public static void main(String[] args) throws IOException {
    var hosts = Paths.get("C:\\Windows\\System32\\drivers\\etc\\hosts");
    var lines = Files.readAllLines(hosts, StandardCharsets.US_ASCII);
    lines.removeIf(line -> line.endsWith("#yuki-mc-server"));

    var ip = Files.readString(Paths.get("your-ip\\ip"), StandardCharsets.UTF_8);
    lines.add("%s yuki-mc #yuki-mc-server".formatted(ip));

    Files.write(hosts, lines, StandardCharsets.US_ASCII, StandardOpenOption.TRUNCATE_EXISTING);
    }
    }


    update-ip.bat
    -----------------------
    cd your-ip
    git pull
    cd..
    java UpdateIp.java
    Oktfolio
        189
    Oktfolio  
       2022-05-12 21:45:34 +08:00
    @eote 别人欺负你 Java 没协程
    agileago
        190
    agileago  
       2022-05-12 21:56:20 +08:00
    zhuangzhuang1988
        191
    zhuangzhuang1988  
       2022-05-12 22:35:14 +08:00   ❤️ 3
    roundgis
        192
    roundgis  
       2022-05-12 23:14:25 +08:00 via Android
    @zmal 他是在哪裡說的?
    zmal
        193
    zmal  
       2022-05-12 23:51:24 +08:00 via iPhone
    @roundgis 微博
    sciel
        194
    sciel  
       2022-05-13 00:17:54 +08:00 via iPhone
    @Seanfuck 可以写一个,从来没用过 php,如果不错,后面去探索一下,我知道一个很厉害的大神也是用 php
    Guaidaodl
        195
    Guaidaodl  
       2022-05-13 00:26:46 +08:00
    @clownpiece 其实 Kotlin 的 Property 可以变成 Java 的 Field, 加一个 @JvmField 的 Annotation 就行. 你说的对内部调用不走 setter 很容易实现的. 在绝大多数情况下, 内部调用 setter 都是正确地做法. 少数特例也很容易实现.

    另外 Java 也在积极吸收 Kotlin 语法, record 了解一下.
    sciel
        196
    sciel  
       2022-05-13 00:40:57 +08:00 via iPhone
    @agileago 感觉还是有点繁琐
    pkupyx
        197
    pkupyx  
       2022-05-13 01:20:57 +08:00
    语法层面的比较其实没意义,核心还是生态。
    java 的优势是 web 工程和 android 生态太好了。
    国内除了超大厂敢上 go ,flutter 之类的,中小厂这么玩很容易坑自己。轮子少,招人难,遇到问题也不容易 google 到。
    agileago
        198
    agileago  
       2022-05-13 07:30:52 +08:00 via iPhone
    @sciel 实际代码从 28 行开始,18 行完成了完整逻辑,还啰嗦?
    xsen
        199
    xsen  
       2022-05-13 07:43:17 +08:00
    @pkupyx #197 恰恰相反,你不知道的是:
    很多连中小厂都算不上的中小企业,很多还是传统行业的,都在选择用 go 这个技术栈

    人是难找,轮子是少,但是,
    1. 别的语言转 go 容易,有经验的 2 周左右;刚毕业 1-2 年的 1-2 个月左右
    2. 大多数轮子都有。部分轮子自己造——不能造,反正都面向接口、服务变成,换 Java 写个服务也不是那么难
    sciel
        200
    sciel  
       2022-05-13 07:51:25 +08:00
    @agileago 仔细看一下 request 方法定义的 i ,和 isRetry,不太能直接看出其用意吧,

    while 里面 else 每次都给 i 重新赋值 5 可能会造成死循环

    41 行 res.code res 也可能会 undefined ,应该先判断一下 res 哇

    getData 里面 没有实际发出 http 请求。。
    1  2  3  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2552 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 10:23 · PVG 18:23 · LAX 02:23 · JFK 05:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.