Joker123456789
V2EX  ›  Java

关于 Java 很啰嗦的问题

  •  3
     
  •   Joker123456789 · May 12, 2022 · 24178 views
    This topic created in 1490 days ago, the information mentioned may be changed or developed.

    我先声明啊,我不是来吹捧 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 在 丰富的生态+强大官方库的 加持下,可以更快完成。

    Supplement 1  ·  May 12, 2022
    补充一点,给我出题的前提是,你们带着自己的代码过来。并说清楚需求
    257 replies    2022-11-14 13:32:01 +08:00
    1  2  3  
    apple2026
        201
    apple2026  
       May 13, 2022
    @sciel 会先判断 if(isRetry),应该不会死循环,感觉还是不太直观
    BigDogWang
        202
    BigDogWang  
       May 13, 2022
    kotlin 表达力真的强?项目里有人写代码 kotlin 特性全用上了,在哪返回一眼都看不清楚
    yazinnnn
        203
    yazinnnn  
       May 13, 2022
    return 处返回啊,这有什么看不清的
    Ziyue
        204
    Ziyue  
       May 13, 2022
    哈哈,喜闻乐见,就喜欢看这种无聊的帖子了.想起郭德纲的相声,喝咖啡高雅,吃大蒜低俗.
    hikarugo
        205
    hikarugo  
       May 13, 2022
    这种贴当娱乐贴看就行了,吵语言,和炒币一样,十年前 csdn 就吵这个,没啥意义
    Loku
        206
    Loku  
       May 13, 2022
    喜闻乐见
    这真的没必要争论。
    每个语言出现的初衷都是针对问题提出的解决方案,肯定是有偏向性的。
    xjay
        207
    xjay  
       May 13, 2022
    以前是哪个项目适合哪个语言就用哪个,现在是哪个老板给钱要用哪个就哪个。
    AItsuki
        208
    AItsuki  
       May 13, 2022   ❤️ 1
    啰嗦还真有一点点啰嗦,但拿来喷就有点刻意了……
    而且 Java 也是一直有在优化了,例如 Jdk7 可以<>省略泛型。Jdk8 的隐式 final 、lambda 、stream ,Jdk11 的类型推导和字符串扩展方法。

    而且选择 go 开发 web 的话,原因根本不是啰嗦不啰嗦的问题……
    fredli
        209
    fredli  
       May 13, 2022
    继续:

    withContext(IO) {
    val okhttpclient = buildOkhttpclient()
    val request = buildRequest()
    val response = okhttpclient.newCall(request).execute()
    if (response.isSuccessful()) {
    withContext(Main) {
    notifyUI()
    startActivity()
    }
    } else {
    doLog()
    }
    }
    Lancer777
        210
    Lancer777  
       May 13, 2022
    @xsen 请问你的数据从哪里得到的,广州 Go 的职位连 Java 的十分之一都没有,就这十分之一里面还有一大半是大厂贡献的,小公司连 Java 的待遇都给不好,更何况给 Go 的了,招人就是小公司最大的难点。
    zorui
        211
    zorui  
       May 13, 2022
    @Alexliu Talk is cheap. Show me the code
    jiayouniu
        212
    jiayouniu  
       May 13, 2022
    @Ziyue 应该是最近在家办公,有时间摸鱼了
    vikaptain
        213
    vikaptain  
       May 13, 2022
    我是写 C#的,也写过一小段时间 java 。相比来说 java 啰嗦是有的,但是两者差别不大。同部门的 C#去写 java 都是一样的感觉。
    我想说 C#比 java 的优势在于加班少
    qbmiller
        214
    qbmiller  
       May 13, 2022 via Android
    go 泛型出来了,加上一些工具包,应该会更好吧。虽然我是个 java…
    不过 java 也在逐渐优化云原生这块
    agileago
        215
    agileago  
       May 13, 2022 via iPhone
    @sciel 你别用 goto,goto 本来就是强烈不建议使用的,再说 js 里面就没有 goto, 你写一个无 goto 的版本看看
    no996
        216
    no996  
       May 13, 2022
    @vikaptain 这不是不同语言的对比和优势,是不同企业的对比和优势
    pkupyx
        217
    pkupyx  
       May 13, 2022
    @xsen 很多这个词,和你自己下面讲的人是难找、还得靠其他语言转,不觉得逻辑上是冲突的么?你这个很多翻译过来,其实叫比例很低但有一定数量。
    apple2026
        218
    apple2026  
       May 13, 2022
    @agileago
    ```
    func fetchData2(ctx context.Context, url string) (*gjson.Json, error) {
    d, err := gclient.New().Timeout(time.Second*3).Retry(5, time.Second*3).Get(ctx, url) // 重试 5 次,每次间隔 3 秒
    if err != nil {
    glog.Error(ctx, err)
    return nil, err
    }
    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("获取数据失败,请稍后重试")
    }
    }
    ```
    才发现,框架自带了重试机制。。
    agileago
        219
    agileago  
       May 13, 2022 via iPhone
    @sciel 这就没意思了
    incompatible
        220
    incompatible  
       May 13, 2022   ❤️ 1
    @ColinZeb 你列举的这个模式匹配跟 java 8 里引入的 stream 、function 没什么本质区别啊。而且说句不客气的,你写的这玩意儿看起来蛮丑的🤷🏻‍♀️

    另外属性和泛型难道 java 没有?
    Leviathann
        221
    Leviathann  
       May 13, 2022
    @incompatible pattern matching 就别洗了,java17-21 的对代码编写改变最大的核心特性就是加 pattern matching 和虚拟线程
    建议学习 oracle 的 java 官方视频看 pattern matching 有什么用以及为什么要加
    cenbiq
        222
    cenbiq  
       May 13, 2022 via iPhone
    C#的灵魂:
    1.早期就加入的 Lambda 。
    2.针对 IEnumerable 接口设计的 Linq 库,任何可枚举对象都可以直接开始 Linq 链式操作,而无需多余操作。
    3.搭配 async/await 的 TPL 库,以及全异步支持,简单好用,协程也不错但学习成本明显高很多。
    4.最重要的,运行时泛型。
    5.property ,代替了 getter/setter 方法。
    6.struct ,只在栈内存中的对象。

    Java 的优势:
    1.生态更佳。
    2.容易且自然的 AOP 编程。
    3.更好找工作。
    xsen
        223
    xsen  
       May 13, 2022
    @Lancer777 #210 招聘职位是少。因为我说的中小厂都不算的传统行业的公司,如物联网、家电、电力这些,go 的岗位都是内部直接转了。很少对外招聘

    因为对外招聘回来的,又不了解本行业的业务
    xsen
        224
    xsen  
       May 13, 2022
    @pkupyx #217 也不算冲突,人难找的意思是因为 go 本身用的人不算多(相对 java 来说),所以出来的人更少。也跟我们要招的前端,还有 c++的一样(其实 c++更少)

    但 go 来说有个好处,就是别的语言的真的很容易转。比如我看到的,包括应届、毕业 1-2 年,或毕业多年( 3 年以上)别的语言开发经验的,如原来做 web 前端的、ios 的、java 的、c++的,都很容易就转过来做 go

    从我看到的数据来说,经验丰富的 2 周左右,不太丰富的 1-2 个月左右
    leaveOnTime
        225
    leaveOnTime  
       May 13, 2022 via Android
    @xsen 没错,字节里面给新人学习 go 的时间就是一两周,然后就开始做一些小需求慢慢就上手了,go 的学习成本或者叫入门成本是比较低的
    pkupyx
        226
    pkupyx  
       May 13, 2022
    @xsen 我在说的观点是对小厂而言 go 的整体生态是劣势,你给的论据翻译成伪代码是这样的:
    func 恰恰相反,go 比 java 对小厂好(goInfo, javaInfo) int {
    if goInfo.go 人难找 {
    if 其他语言很容易转 go {return 1}
    }
    }

    难道不应该是这个逻辑么?
    if 只要 go 人比 java 难找 {return -1}


    语言对超大厂的候选人才来讲,切换确实不大是问题,但仍然是小问题。而对小厂对标的人才群体来说则是不太小的问题。
    stuazt
        227
    stuazt  
       May 13, 2022 via iPhone
    就不说其他的语言,楼主哪怕稍微试试 kotlin 呢?你试试,就不会发这个帖了。Java 语言能力没啥问题啊,但确实写起来很麻烦,相对于一些比它新的语言。
    hepin1989
        228
    hepin1989  
       May 14, 2022
    Scala 可以秒杀 Golang 的抽象能力
    hepin1989
        229
    hepin1989  
       May 14, 2022
    @zmal 并不是,为了更好圈钱而已。
    incompatible
        230
    incompatible  
       May 14, 2022
    @Leviathann 为什么加啊?为了把代码写得像我引用的那坨一样丑吗? 笑
    msg7086
        231
    msg7086  
       May 14, 2022 via Android
    我厂,我之前碰的代码,原本是 JDK7 ,没有 var ,没有 lambda ,没有 map reduce ,写异步并行需要用 future 。

    过了一年,经过层层老板研究决定,批准升到 JDK8 。

    有 map reduce 了,有 lambda 了,有 parallel stream 了,还是没有 var 。

    然后过几个月我就接到了个 JDK1.6 的项目。
    jy02201949
        232
    jy02201949  
       May 14, 2022
    结合上一个《 java 很重》的帖子,让我联想到了那个笑话:
    jy02201949
        233
    jy02201949  
       May 14, 2022
    女:如果你能让这个论坛里的人吵起来我就跟你睡
    男:发帖“PHP 是最好的语言”
    女:我先去洗澡我会兑现我的承诺
    20 分钟后
    女:我洗好了,你怎么还在电脑前
    男:我今天非得说服这帮人,PHP 就是最好的语言
    hrn961110
        234
    hrn961110  
       May 14, 2022
    @Alexliu 一个 map 转 bean ,vo 里面放个方法这很难么
    Xrtero
        235
    Xrtero  
       May 14, 2022
    后排吃瓜🍉
    nnegier
        236
    nnegier  
       May 14, 2022 via Android
    我以为是 jvm 党呢,原来是 java 党,kotlin 这种几乎一样也能回复争论一把
    v2vTZ
        237
    v2vTZ  
       May 14, 2022 via Android
    我也觉得这么多少争赢了也意义不大,在我看来 Java 的啰嗦反倒是个好处,作为第一门语言学习挺规范的
    FrankHB
        238
    FrankHB  
       May 14, 2022   ❤️ 1
    半斤八两?你直说吧,就是欺负人家在有选择的前提下懒得写啰嗦业务代码罢了。真写得写不出来明显两码事好不。
    比如就实现操作系统这个业务,真有人汇编写出来比你 C 写得啰嗦得多,你还能咋地,批判不够半斤八两?(别忘了 C 之前基本都用汇编写操作系统。)


    @Macolor21
    > Java 不断被喷的原因就是,每一行代码都必须清晰的表达用什么类型,做了什么事情,看起来像个啰嗦老太婆,但实际上每一行代码都特别清晰。

    每一行代码都必须清晰的表达用什么类型 ×
    清晰地自以为是 √

    比如 Java 10 之前死皮赖脸不肯加 var ,因为一些人自以为没声明显式类型就是“不够清晰”(甚至加了之后还有人想反攻倒算的)。
    殊不知有的场景的详细设计就明确要求这里对具体类型进行关注点分离,强调符合设计的类型是满足某特定约束的“任意一种”,而 Java 的类型系统甚至还没能力描述清楚 sum type ;还要求写清楚具体类型那就是妥妥地扯可修改性后腿,反过来毒害设计。
    这里被喷的主力就是类似这样的脑补他人合理实际需求不存在,又不懂替代解决方法的自以为是的用户。在某些领域,这些用户被称为民科。
    (当 Benjamin C. Pierce 都在反思 more typed 是不是 more expressive 的时候,又哪来这些民科误导舆论的空间呢?)

    > 可能一部分人为了显得自己与众不同,高人一等,所以它们倾向于学习成本更高,看起来更简练的语言。

    不巧的是,Java 用户中,这类人相对别的语言的用户特别多。于是对剩下的不少用户来讲,与其一个个纠正,还不如先润为敬,反正就是 JVM 生态也有不少别的替代。这样,黑起来就更容易了,不怕误伤友军。
    从一开始就不依赖 Java 的旁观者来看,你们这点破事还是省省的好。非得站队,那自然是优先消灭妄图按闹分配的老古董的,免得还有来不及补课基础不牢靠的死硬分子找到借口反智,故意拎不清楚到底是谁在与众不同。——麻烦记住,没人逼你编程来搅乱市场。
    xsen
        239
    xsen  
       May 14, 2022
    @pkupyx #226 go 而言呢
    1. 对应届或毕业 1-2 年的新手友好,极易上手
    2. 对有多年别的语言经验的切换成本极低,不会有任何难度;单纯就是意愿的问题

    所以采用 go 技术栈,对说不上名字的中小微厂来说是极其划算的
    xsen
        240
    xsen  
       May 14, 2022
    @v2vTZ # 237 要规范,不如汇编。寄存器都要指定,更规范。哈哈哈
    pkupyx
        241
    pkupyx  
       May 15, 2022
    @xsen java 现在同样对新手友好极易上手啊。
    而且你一直回避我说的逻辑问题:

    go 对中小厂好坏得分 = 0

    if go 人少,招聘成本高 {
    得分 -= 10 // 这是我的逻辑
    if 其他语言很容易切到 go {
    得分 += 20 // 如果+=5 我认同,但不等于恰恰相反,并且仍然是 go 的劣势。如果你要+=20 那我只能 reject ,先实现思维与价值判断的正确逻辑吧。。。
    }
    }
    Aloento
        242
    Aloento  
       May 15, 2022
    你们在那聊什么托管类语言的代码行数有意义吗?你当你在写 JS 呢?
    托管类代码写多少都不重要,重要的是 IL 出来的操作指令数,和实际执行的 CPU 周期
    C# 有一个 Bug https://github.com/dotnet/runtime/issues/4207
    你写短的代码,ASM 有可能还更长

    而且 Java18 才干了一件在.NET 里面干就会被社区炎上的事情
    https://openjdk.java.net/jeps/410
    然后我才知道 OpenJDK 没有 AOT 和 JIT...
    Aloento
        243
    Aloento  
       May 15, 2022
    而且 OP 你拿一个完全托管类语言( JVM )跟 Native ( Go ,虽然它也有简易 GC )语言比
    虽然它们都可以实现同一个需求,但这俩本就不在一个世界里,这不是自讨苦吃和引战么...
    Inf1nity
        244
    Inf1nity  
       May 15, 2022
    @Aloento #242 JEP 410 只是说移除 Graal 项目引入的实验性 AOT 和 JIT Compiler ,而不是 “OpenJDK 没有 AOT 和 JIT”。OpenJDK 是有 JIT 的,被移除的 AOT Compiler 是 Graal 项目的产物。
    Aloento
        245
    Aloento  
       May 15, 2022
    @Inf1nity 原来如此,因为完全没使用过相关功能所以就没了解过
    那它有 AOT 吗
    Inf1nity
        246
    Inf1nity  
       May 15, 2022
    @Aloento #245 AOT 编译器是 JDK 9 从 Graal 项目中引入的,这些在你之前的回复中提到的 JEP 410 里面讲的很清楚,里面提到了 JDK 的 AOT 编译器是什么时候引入的,又是为什么移除了。
    Aloento
        247
    Aloento  
       May 16, 2022
    @Inf1nity 学到了,我还以为它也有另外的 AOT ,因为按它那么说 JIT 是有两个,一个是从 Graal 来的,对吧
    mmdsun
        248
    mmdsun  
       May 16, 2022 via iPhone
    go 语言语法最拉了完全比不过 Java 。。

    但 C sharp 是比 Java 语法好,首创 async/await 方案被多个语言采纳认可。还有 Rx 扩展库,现在的 Rxjava 和 Java 的反应式编程 Reactor Projects 都是吸纳的.NET 库方案。C#的 Linq 语法,把 SQL 语言都弄成关键字了,select from join 都能直接写代码里面不用字符串引号当然有对应的成链式函数 API 。C#还有各种扩展函数,?空安全这几个都被 kotlin 借鉴去了。

    说到 Java 语法,我想说 Java 的事件、接口回调 Java 很麻烦要各种 new 和 setListener 。C#有事件的关键字和类型。+=可以添加删除事件和多播事件。比如:

    public event EventHandler<EventArgsType> EventName;
    EventName += (obj, args) => { /* Handler logic */ };
    golangLover
        249
    golangLover  
       May 16, 2022 via Android
    @aragakiyuii 请问这是什么主题,挺漂亮
    zmal
        250
    zmal  
       May 16, 2022
    @hepin1989 你知道邓草原是谁嘛说人家圈钱?扣帽子扣挺快啊?家里帽子得堆到房顶了吧?
    aragakiyuii
        251
    aragakiyuii  
       May 16, 2022   ❤️ 1
    @pkwenda
    @golangLover
    用的 idea ,主题买的 Dracula Pro
    dsggnbsp
        252
    dsggnbsp  
       Oct 28, 2022
    对对对对对对哈哈哈,学前端的来报道,要 比就比谁早下班呀~
    jinsongzhao
        253
    jinsongzhao  
       Oct 28, 2022
    @ColinZeb 拿 kotlin 这些来证明作用不大,java 核心设计团队总是,等社区考验新特性后,把确定成熟的特性加入 java 。这个思路也是 C++使用的。这种完美主义思想导致它们曾经升级非常慢,然后领先的技术慢慢被追上,各种新语言起来了,它们似乎才放弃了完美主义,积极加入新特性,版本升级提速。
    hez2010
        254
    hez2010  
       Oct 28, 2022
    @lawler 能说出 C# 是 Java 语法糖的才真是想笑。两个语言类型系统的差异太大了。
    ColinZeb
        255
    ColinZeb  
       Oct 30, 2022
    @jinsongzhao 属性替代 get setter 似乎没有提上日程,这也不是什么实验特性吧
    jinsongzhao
        256
    jinsongzhao  
       Nov 5, 2022
    @ColinZeb 手动写 get set ,也是洁癖一种,OO 思想里,通过 get 和 set 方便加入其他操作,于是方便改造老系统,如果只是纯粹为了取值赋值,可以不存在
    ColinZeb
        257
    ColinZeb  
       Nov 7, 2022
    @jinsongzhao 可以不存在为什么 java 里一大堆空 getField setField 方法。
    jinsongzhao
        258
    jinsongzhao  
       Nov 14, 2022
    @ColinZeb 因为 OO 思想曾经非常泛滥,曾经到处都在用 24 设计模式,但热潮总会退去,OO 的啰嗦解决的是多人团队开发和后期迭代,但是代码也需要简洁和文档化。个人觉得曾经科班出身和非科班最大区别就是,科班的会用一套 OO 架构设计较大的软件,这样方便团队开发,后期迭代和改造。然而我觉得 Linus 说一句话很对,OO 设计出来架构总能有更好的设计出现,目前还没有完美的 OO 设计,所以他更喜欢 C ,而不是 C++。
    1  2  3  
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   881 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 114ms · UTC 20:43 · PVG 04:43 · LAX 13:43 · JFK 16:43
    ♥ Do have faith in what you're doing.