
多年以前我看到一篇神奇的文章 Java for Everything, 其中提出了一个大胆的想法:就连脚本小工具都用 Java 来写。
我读了这篇文章,但并没有立即使用 Java, 而是写了一段时间 Go, 又写了一段时间 Python, 最近想起这篇文章,就想用 Java 写点东西。
本来 Java 是很嗦的,这是它最被诟病的地方了。
但现在 Java 有了 record, lambda, Stream API, var(类型推断) 等等, 已经变得不是太嗦了,根据我狭隘的个人经验,甚至认为比 Go, Python 更简洁。
if err != nil, 代码是很简明易懂, 但论代码的简短,也是经常比不上 Java 。以前我喜欢用 Go 来做一些自用的小软件,做一个本地网站通过访问网页来使用, 最近想做一个叫 monostich 的小工具,就尝试用 Java 来做。
monostich 的功能非常简单。
这次我用 Javalin 来做本地网站,并且采用了以前我写 Go 时的代码组织方式, 因此两种语言可以做个对比。
可见, Go 与 Java 的代码几乎一模一样:
// github.com/ahui2016/dictplus/blob/main/main.go func main() { e := echo.New() e.Static("/public", "public") e.File("/", "public/index.html") api := e.Group("/api", sleep) api.POST("/get-word", getWordHandler) api.POST("/add-word", addWordHandler) api.POST("/update-word", updateWordHandler) api.POST("/delete-word", deleteWordHandler) api.POST("/search-words", searchHandler) e.Logger.Fatal(e.Start(*addr)) } // github.com/ahui2016/monostich/.../App.java public class App { public static void main(String[] args) { Javalin app = Javalin.create(config -> config.addStaticFiles(staticFiles -> { staticFiles.hostedPath = "/"; staticFiles.directory = "/public"; staticFiles.location = Location.CLASSPATH; })).start(port); app.post("/api/insert-poem", Handle.insertPoem); app.post("/api/update-poem", Handle.updatePoem); app.post("/api/delete-poem", Handle.deletePoem); app.post("/api/get-poem", Handle.getPoem); app.post("/api/search-poems", Handle.searchPoems); } } 可见, Go 比 Java 多了一些 if err != nil, 其余代码几乎一模一样:
// github.com/ahui2016/dictplus/blob/main/handler.go func addWordHandler(c echo.Context) error { w := new(Word) if err := c.Bind(w); err != nil { return err } if err := db.InsertNewWord(w); err != nil { return err } return c.JSON(OK, Text{w.ID}) } // github.com/ahui2016/monostich/.../Handle.java static Handler insertPoem = ctx -> { var form = ctx.bodyAsClass(PoemForm.class); var poem = db.insertPoem(form); ctx.json(poem); }; 在上面 Handler 的代码中, db.InsertNewWord() 与 db.insertPoem() 的具体实现如下所示。
可以看到, Go 的代码还是受到了 if err != nil 的困扰,显得很嗦, 而 Java 采用 Stream API 的好处是非常明显的,代码简洁了很多。
// github.com/ahui2016/dictplus/.../database.go func (db *DB) InsertNewWord(w *Word) (err error) { tx := db.mustBegin() defer tx.Rollback() if w.ID, err = getNextID(tx, word_id_key); err != nil { return } w.CTime = util.TimeNow() if err = insertWord(tx, w); err != nil { return } err = tx.Commit() return } // github.com/ahui2016/monostich/.../DB.java Poem insertPoem(PoemForm form) { return jdbi.withHandle(handle -> handle.inTransaction(h -> { var poem = new Poem(getNextId(h), form.title(), form.stich(), Util.now()); h.createUpdate(Stmt.INSERT_POEM) .bindMap(poem.toMap()) .execute(); return poem; })); } 本软件后端采用 Javalin, 前端采用 mj.js, 相关介绍请看以下链接。
2 lisongeee Aug 31, 2022 呃呃,既然追求代码简洁,为什么不试试神奇的 kotlin 呢?  |
3 zbatman Aug 31, 2022 有请双方辩手入场 |
4 hccsoul Aug 31, 2022 我先来 ,java 是世界上最优秀的语言,杠我的去和楼主对线 / |
5 imzcg2 Aug 31, 2022 不能自动写代码完成任务的都不是最优秀的图灵完备语言 |
6 justanetizen Aug 31, 2022 呃,java 8 连 UTF8 处理起来都麻烦,不知道你们为毛还要抱残守缺。 |
7 WispZhan Aug 31, 2022 via Android 为什么不看看其他 JVM 语言呢? |
8 dqzcwxb Aug 31, 2022 @justanetizen #6 细说 |
9 zed1018 Aug 31, 2022 如果一定要 everything 我选择 kotlin ,java 有的我都有,我有的 java 真不一定现在就有,而且 non-nullable type 这个对我来讲太刚需 |
10 SuperMild OP @qW7bo2FbzbC0 一直听说 C# 的优秀,以后找个机会研究研究学习学习。 @lisongeee kotlin 用了更多函数式编程方法,我脑子不太够用,总觉得 kotlin 用起来反而比 java 更累,java 还是比较直白的。 |
11 lllllliiii Aug 31, 2022 然后这个写 Java for everything 的人的 github 的置顶项目没有一个 Java 写的。太搞了哈哈。 |
12 wuxqing Aug 31, 2022 如果不搞 spring 那个体系,https://solon.noear.org/ 这个看着也很简洁。 |
13 lllllliiii Aug 31, 2022 @wuxqing #12 solon 就代码组织形式跟 spring 就什么区别吗? |
14 cyningxu Aug 31, 2022 kotlin ,你是我的神! |
15 Veneris Aug 31, 2022 via iPhone go 打成二进制包就可以了,java 需要 jre ,不过反过来说 java 因此也是跨平台的了,这一点是优点还是缺点见仁见智 但是 java 打出来的包体积,启动后的内存占,普遍要大一些,有时候我只是想写个玩具项目而已,总给我一种很笨重的感觉 另外,kotlin 可以 native 了,不过还没有具体尝试过 |
16 Leviathann Aug 31, 2022 @Veneris kotlin 的 native ,目前还不如借助 graalvm 的 jvm native |
17 proxychains Aug 31, 2022 我先来 感觉不如 php...java |
19 TWorldIsNButThis Aug 31, 2022 @SuperMild 恩 习惯 kotlin 的 lambda 算是一个坎,lambda 也是 kotlin 语法魔术的核心 另外 kotlin 也比较推崇灵活变换隐含的 receiver 来实现更接近自然语言的表达 |
20 Huelse Aug 31, 2022 来体验下 scala fp 吧 |
21 makelove Aug 31, 2022 java 还是不太行,很多年没写过 java 了,当年觉得 java 实在算不上好用,比如没有关键字参数,不知道现在有没有了 |
22 wdhwg001 Sep 1, 2022 via iPhone @qW7bo2FbzbC0 我私底下觉得这纯属微软管太宽了,啥都是第一方的,所以社区没有造轮子的热情。 这个策略本身就不对,正确的是把基础的打好,然后 fund 一些好的第三方框架,出钱出力去帮忙补测试覆盖,提升性能和出钱 audit 代码。 |
23 CodeCodeStudy Sep 1, 2022 java17 支持多行字符串了吗 |
25 qinxi Sep 1, 2022 @CodeCodeStudy #23 该更新了 https://openjdk.org/jeps/378 |
26 keepfun Sep 1, 2022 看了下 好牛逼 和 spring boot 完全两个样子 和 go 挺像的 |
27 fgwmlhdkkkw Sep 1, 2022 那你有什么理由拒绝 kotlin 呢?还有 async 用。 |
28 CodeCodeStudy Sep 1, 2022 @qinxi #25 感谢! 20 年才搞这个,晚了点吧,早就该推出来了 |
29 EthanZC Sep 1, 2022 scala YYDS |
30 wetalk Sep 1, 2022 Kotlin ,Scala ,Groovy 任君挑选 |
31 SuperMild OP @fenglangjuxu 是呀,我从 Go 转过来感觉很舒服。但如果正经项目还是用 spring boot 比较好,业余小项目用 Javalin 很方便。 |