距离 java9 发布还有两个月,可惜语法居然没啥变化,现在 java 的语法糖实在太少了,写久了有点没意思啊
1
0915240 2017-06-03 19:21:37 +08:00
貌似主推 jigsaw 了
(还)算不。 |
3
littleshy 2017-06-03 22:30:15 +08:00
新项目直接上 Kotlin 啊。
|
4
xiparos 2017-06-03 23:40:42 +08:00 1
因为纯 java 程序员真心不懂那么多语法糖啊(逃
|
5
tlday 2017-06-04 00:16:08 +08:00 via Android
java 的优势不就在没有太多语法糖么
|
7
gouchaoer 2017-06-04 00:36:30 +08:00 via Android
语法糖根本没用
|
8
ihuotui 2017-06-04 00:39:18 +08:00 via iPhone
编译后有什么变化?性能?
|
9
svenFeng 2017-06-04 00:50:57 +08:00 via Android
你渴望魔法的力量吗?加入括号教吧
|
11
Monstercat 2017-06-04 01:08:14 +08:00 via Android
要语法糖何用 我们有足够 nb 的 ide😏
|
14
tedzhou1221 2017-06-04 09:38:01 +08:00
语法糖?好吃吗? 吃了就会语法?哈哈
有 Idea,何必语法糖呢 |
15
sagaxu 2017-06-04 10:14:27 +08:00
所以我放弃 Java 了,转投了 Kotlin,花了不到一个星期时间,开发效率就超过写了 5 年的 Java。
map-filter-reduce 行云流水般的写法,太舒适了,不过读代码的人如果没有函数式思维,要头大了。 |
16
zgqq OP @sagaxu 主要后台用 kotlin 太少了,另外这几个操作 java8 的 stream 都有吧
|
17
sagaxu 2017-06-04 10:21:36 +08:00
@tlday 范型不过是编译器通过类型擦除加了点糖,所以不要用,Java 7 的 try-with-resource 也不要用,它也是语法糖,还是手动写 finally 释放资源吧。很多新加入的库,也是通过老库自己就能实现的,原则上算是库的糖,干脆也不要用。
|
18
sagaxu 2017-06-04 10:30:50 +08:00
@zgqq 后台用 Kotlin 不会像 Android 那样宣传,所以感觉是少了,其实也不少。Java8 的 stream 也能这么写,但是要罗嗦的多,我之前就是用 Java8 的写法,看到 Kotlin 的简洁,马上就尝试了,然后就一发不可收拾。
|
19
Cbdy 2017-06-04 10:41:54 +08:00 via Android
主推模块化和一些 api (货币 api ?)挺期待的,到时候估计模块化工具会大改( maven、gradle )
|
20
WispZhan 2017-06-04 10:52:51 +08:00 1
@sagaxu
Java 这种半残的泛型才是类型擦除,像 C#或者 C++这样的泛型就不存在类型擦除。所以说泛型并不是简单的被语法糖包裹,只是 Java 是这种形式而已。 --- @tedzhou1221 没必要鄙视语法糖,语法糖的目的就是为了简化代码的书写复杂度,减少人工录入的重复代码量。IDE 自动完成或者补全和编译器的语法糖的出发点都是这个。 |
21
msg7086 2017-06-04 11:10:04 +08:00
Java 本来就是个工业化的语言,适合一大堆不同风格的人凑一起写代码。
因为技巧少,语法糖少,写法死板,所以大家都能写出一样的代码来,适合码农式的开发环境。 Python 也差不多,提倡 Pythonic 就是为了擦除不同人之间的个性,大家都写出一样的代码来,读别人的代码也简单。 你想要写起来爽,为什么不去找一个一开始就写起来爽的语言呢。 |
22
sagaxu 2017-06-04 11:19:43 +08:00
@WispZhan C++的范型一样是语法糖,C 语言没有范型,就要复制粘贴代码了? C++的确定性析构,在 C 里一样可以用 goto 实现啊,也算是语法糖。高级语言本身可不就是低级语言的语法糖么?
|
23
yidinghe 2017-06-04 11:34:15 +08:00 via Android
语法变化不大,主要是结构化和新增一些 API。
|
25
sagaxu 2017-06-04 11:40:26 +08:00
@msg7086 代码可读性强弱是因为语法吗?我觉得不是,宏观的架构,和微观的算法,加上对业务的理解,才是可读性的关键。用 Java 大家都写出一样的代码?不一定。
四种不同的循环的写法,对可读性的影响,远不如一个简单的算法,不信去看 ACM 解题的 Java 代码,有时行行都懂,就是看不明白原理。 |
26
SilenceCode 2017-06-04 14:54:08 +08:00 via iPhone
主要结构性变化
|
27
darouwan 2017-06-04 17:40:10 +08:00
我真的不懂要那么多语法糖干什么。。。
|
29
msg7086 2017-06-04 17:51:36 +08:00
@sagaxu 我说的可读性是指在同等水平下写出来的代码的可读性。
比如之前我出过的一道面试练习题: 螺旋形打印出一个二维数组,比如 spiral_print([ ['a','b','c','d'], ['e','f','g','h'], ['i','j','k','l'] ]) # -> 'aeijklhdcbfg' spiral_print([ ['a','b','c','d'] ]) # -> 'abcd' 这题用 Ruby 写的话,答案是这样的: def spiral_print m m.empty? ? '' : m.map(&:shift).join + spiral_print(m.reverse.transpose) end 你可以试着用 Java 写一下,然后横向对比一下可读性。 |
30
tlday 2017-06-04 17:57:12 +08:00
@sagaxu 你走另一个极端了,语法糖有优点有缺点。语法糖的极致就是 ruby 这样,我也写 ruby,但是我会尽一切可能避免在重量级产品环境中使用类似 ruby 这种语言,它写起来很爽,我可以用 ruby 炫技,写出各种让你“还有这种操作”的代码,但是维护的时候,特别是换人维护的时候,会是噩梦。
我对 kotlin 持开放态度,它解决了很多问题,提升了很多开发效率,我相信 android 或类似的领域,kotlin 会大放异彩。但是 java 就是 java,更少的语法糖就是 java 的优势,它不叫 jetlin,它没有必要成为另一个 kotlin。已经有一个 kotlin 在这里了,我们为什么要创造另一个 jetlin 呢。我认为我们这个帖子是在讨论 java,你说呢? |
31
micean 2017-06-04 18:33:06 +08:00 1
写了这么多年 java,都为需求头疼,从来没为语法糖头疼
一方面讨厌括号深嵌套,另一方面又赞赏各种炫酷的语法糖 做人为什么要这么纠结…… yin 神有句话我很赞同,别用肉眼去 parse |
33
murmur 2017-06-04 18:56:29 +08:00
java 从来没说用 java1.8 鄙视 java1.6 + apache utils
java 从来没靠语法胜出 靠的是宇宙最强虚拟机+第二强 IDE+最完善开源生态 |
35
sagaxu 2017-06-04 19:57:18 +08:00 1
@CRVV C 不是自带了一个 qsort 吗?
@msg7086 我不懂 ruby,但是不到一分钟就 get 到原理了,Java 版的更好懂更好维护吗? import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class Print { private static <T> List<List<T>> tr(List<List<T>> m) { if (m.isEmpty()) { return Collections.emptyList(); } List<List<T>> n = Stream.generate(ArrayList<T>::new).limit(m.get(0).size() - 1).collect(Collectors.toList()); n.forEach(ts -> m.forEach(t -> ts.add(null))); for (int i = 1; i < m.get(0).size(); i++) { for (int j = 0; j < m.size(); j++) { n.get(i - 1).set(m.size() - j - 1, m.get(j).get(i)); } } return n; } private static <T> String spiral_print(List<List<T>> m) { if (m.isEmpty()) return ""; StringBuilder b = new StringBuilder(); m.stream().map(chars -> chars.get(0).toString()).forEachOrdered(b::append); return b.append(spiral_print(tr(m))).toString(); } public static void main(String[] args) { { List<List<Character>> m = new ArrayList<>(); m.add(Arrays.asList('a', 'b', 'c', 'd')); m.add(Arrays.asList('e', 'f', 'g', 'h')); m.add(Arrays.asList('i', 'j', 'k', 'l')); System.out.println(spiral_print(m)); } { List<List<Character>> m = new ArrayList<>(); m.add(Arrays.asList('a', 'b', 'c', 'd')); System.out.println(spiral_print(m)); } } } @tlday 我始终觉得语法糖这事情,因团队而异,一个人的团队,想怎么写都行。两个人或者人更多的时候,最简单的办法就是看这个团队的中位数工资,8K 的团队,跟 30K 的团队,对语言的要求是完全不同的,8K 眼里的难懂的奇淫技巧,在 30K 眼里可能只是稀松平常。都用 Java,8K 的人看 30K 写的代码,很容易看不懂,30K 看 8K 的很容易心情烦躁,都不利于维护。 |
36
CRVV 2017-06-04 21:50:31 +08:00
@sagaxu
qsort 和 std::sort 的语义不一样。从结果来说,qsort 比 std::sort 慢得多。这不叫实现了范型的 std::sort http://www.geeksforgeeks.org/c-qsort-vs-c-sort/ |
37
sagaxu 2017-06-04 22:27:11 +08:00
@CRVV 语义是一样的,只是性能不同,qsort 也能用 macro 封装,https://github.com/ahmadsalim/qsort-inline,这样就没有函数调用开销了,多态也可以通过函数指针模拟,内核 VFS 不就这么干的么。
|
38
msg7086 2017-06-05 06:54:05 +08:00
@murmur 只是随便举个语言表达能力的例子而已。
业务上有很多类似的东西,比如 select+map+tap 写 oneliner 在我们自己系统的 Ruby codebase 里是很常见的。 相对的至少 Python 和 Java 都是很少很少会写那种 oneline code 的。 @sagaxu 你 Get 到原理是因为有题目做铺垫。 假如没有题目,就给你函数体那一行然后问你这函数是干啥的,你可能会纠结不少时间。 至于这个 Java 代码,看上去像是直接从我 Ruby 代码上翻译的? 你试试看正常写这道题,用 4 个循环,从第一列,最后一行,最后一列到第一行分别拿出字符放进 SB 里,这样写,不要强行去套 transpose。 不过你这最后一段说得很有道理,我很赞同。 |
39
sunboy911 2017-06-05 09:39:25 +08:00
大家要搞清楚,谷歌只是承认了 Kotlin 是开发安卓的官方语言之一!!!
|
40
araraloren 2017-06-05 10:17:19 +08:00
@sagaxu
语法糖、语法糖,没有语言的支持,C 就算能模拟任何东西,再牛逼也不能这么写 ``` template <typename T> void qsort(T* beg, T* end, int (*f)(T*, T*)) { # sort } ``` |
41
srx1982 2017-06-05 10:41:07 +08:00
Kotlin 就行了
|
42
af463419014 2017-06-05 10:58:22 +08:00
当公司把一个已经开发了两年的项目交给你加新功能的时候,你才会知道,语法糖什么的一点也不好玩
|
43
bk201 2017-06-05 11:35:11 +08:00
语法糖会降低代码可读性,写起来是爽,别人看起来就会很不爽。
|
44
sagaxu 2017-06-05 12:36:07 +08:00
@af463419014 去年恰好接手了一个两年的项目,我先把 Java6 升级到 Java8,再把 spring3 升级到 spring4,然后把 maven 迁移到 gradle,最后引入 Kotlin 混合开发,除了新增文件都是 Kotlin 以外,偶尔得闲了还不忘挑一两个 Java 文件转换成 Kotlin,夹带在版本中一起测试发布,迁移还是比较平稳的。
Java 不是语法糖不足的问题,它是落后现代语言太多,不跟别的比,就跟 C#比,它的语法也显得有些老态龙中了。如果我同事 low 到连一点儿最基本的语法糖都成为障碍,我会考虑换同事,或者换工作,不会迁就培训班水平的同事。 |
45
ren2881971 2017-06-05 13:13:50 +08:00
我特么还用 1.6 呢 就算出到 12 又与我何干!
|
46
af463419014 2017-06-05 13:42:15 +08:00
@sagaxu
能接手以前的项目还玩的这么溜,你很厉害 我 kotlin 也就写了 hello world 的水平,有时间我也多写写,毕竟写了,才能更好的理解它的优点和缺点 另外语法糖成为障碍这种事应该不至于,我只是认为同一个功能,可能有多种语法糖可以实现,而大家在没有标准的情况下,可能不同风格的代码在同一个工程里,导致代码混乱(纯属猜测,没有实践,js 里这样的情况倒是很常见) |
47
sagaxu 2017-06-05 14:21:48 +08:00 1
@msg7086 Python 现在也经常有人写 list/dict/set comprehension 了,偶尔还会有两层甚至三层的 comprehension,Java 不这么写,只是因为长期以来一直语法罗嗦不方便这么写,Java8 稍稍改进了一点但还是不够简洁。
我举个例子试着对比一下可读性和罗嗦之间有没有关联,先来个 Java 版的 https://gist.github.com/anonymous/b7361b54a68afe154f9a4eb01ad0e228 71 行代码,原汁原味的 getter 和 setter,sortByAgeA 和 sortByAgeB 分别用了 Java7 和 Java8 的 style,更罗嗦的 Java7 可读性更高吗?我不觉得。 再看一下 Kotlin 的写法, https://gist.github.com/anonymous/ba398be974f1861256a5770eb33b009c 只有 13 行代码,没有 getter/setter,连 toString 都自动合成了比较理想的形式,sort 的方法太简短,以至于专门定义个方法都显得多余。 more verbose 并不能得到 more readable,两者相关,但没有因果关系,再举个例子 a = a * b 和 assign a * b to a 比,后者更 verbose,而且不会让初学者对等号产生疑惑,但它可读性如何呢? |
48
Ouyangan 2017-06-05 18:09:09 +08:00
idea 可以自动转换成语法糖....
|
49
wangxiaoer 2017-06-08 16:49:33 +08:00
@anyele 效率?你还在纯手写吗? 纯 java 语言没有任何糖和各种符号,就一个 `.` 用于方法调用和属性引用,(箭头符号是后来的),这就意味着脑子稍微正常的读一个新的 java 项目毫无难度,就跟看小说一样,更不用提母语是英文的认了。
有些语言各种 $ & @ > >> << 乱入,真是看起来头大。 |
50
anyele 2017-06-08 17:16:09 +08:00
@wangxiaoer #49 看起来头发说明你不熟, 学习新语法不就行了?
|
51
gnaggnoyil 2017-06-11 03:16:01 +08:00
@sagaxu C++模板的 partial specialzation 你给我语法糖一个;异常和 CPS 变换你给我用 C 语法糖一个.
|
52
sagaxu 2017-06-11 10:24:21 +08:00 1
@gnaggnoyil 有什么软件是必须用 partial specialzation,不用就做不出来的? C 里的异常不就是用 goto 和 setjmp 做的么?语法糖无非就是少写几行代码,它不会给语言增加原来没有的能力。
|
53
sagaxu 2017-06-11 10:41:30 +08:00
@wangxiaoer 脑子稍微正常的人,学个面向大众的新语言也是毫无难度,跟看小说一样,最多几天就学会了。语法是为这门语言的用户服务的,还是为熟悉别的语言但是不愿意熟悉这门语言的其他语言用户服务的?
|
54
wangxiaoer 2017-06-11 11:37:09 +08:00 via Android
@sagaxu 人肉 parse 代码 Java 基本是 0 成本。
|
55
sagaxu 2017-06-11 15:02:35 +08:00
@wangxiaoer 你说的那是 Java <= 6,一个死守 Java 6 的人,看到 Java7 和 Java8 的新特性,也会 parse 不了的。随便举几个例子。
Java 7 的 try-with-resource 让人一愣,Java 7 的 multi-catch 会让人思考 exception 的类型顺序, Java 8 就更多了,lambda 表达式,stream 和并行 stream,随便拿个官网例子 double average = roster .stream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge) .average() .getAsDouble(); 不熟悉 Java 8 的人 parse 起来真的 0 成本吗?而且即将发布的 Java 9,往这个方向越走越远,简单到不学就能用的日子,已经是过去时了。 |
56
wangxiaoer 2017-06-11 18:44:28 +08:00 via Android
@sagaxu 我们生产环境在用 8 感觉 parse.起来没啥压力。
总之感觉靠着 Ide 可以闭着眼睛写 Java ,但 Python 总感觉无法下手,写起来小心翼翼 |
57
sagaxu 2017-06-11 21:10:14 +08:00
@wangxiaoer 你用 Java 8 没压力,不正好说明它增加的那些语法糖不会带来额外的人肉 parse 成本么?::和->这种新增的运算符也没那么难懂。
Python 我读起来也毫无压力,写的话除了 IDE 补全差点,重构功能弱点,其它也还好。只有 haskell 这类语言让我觉得有点阅读负担,那也只是因为我没有学过,如果我愿意学,读起来不会比 Java 费力。 |
58
zgqq OP @sagaxu java8 的 stream,如果没有学过,根本没有读好吗,现在集合操作都是用 stream 还被同事说秀操作我特么也是醉了
|
60
phx13ye 2017-06-11 23:52:37 +08:00
赞“ more verbose 并不能得到 more readable ”
可读性都是建立在熟悉程度上的,觉得更可读只是自己习惯了罢了 |
61
wangxiaoer 2017-06-12 08:20:44 +08:00
@zgqq 我觉得如果有 js 开发经验,就不说 es6 了,jquery understore promise 这些库用过的话,那些流式操作符应该不难懂。
|
62
wangxiaoer 2017-06-12 08:28:08 +08:00
@sagaxu 及时这样,我仍然觉得 java 的那些语法糖(各种符号)相对还是少的。我觉得 java 最简单的地方在于他的认知统一,比如当你面对一个陌生的对象、数据结构,你不清楚有哪些 接口,输入一个点,IDE 直接全出来了。因为 java 里面大多数就是 xxx.y xx.y()这种操作。
Python 这种,完全抓瞎,你想计算一个字符的长度,s.length? s.size? 特么的猜了半天发现是 len(s), 但是别的地方又有 xx.y()这种,这就是严重的割裂,让人无所适从。基本上离了文档没法写,可是计算一个字符串长度而已,我看哪门子文档啊。 所以见到推荐 python 入门,觉得 python 简单的,我都难受,真心不如 js 入门好受。 |
63
Miy4mori 2017-06-12 09:05:11 +08:00 via iPhone
@wangxiaoer 我也想吐槽 python 这种 pop 和 oop 混搭的标准库,哈哈哈。
|
64
svenzhao 2017-06-12 09:54:05 +08:00
有些人真搞笑... 怪不得 java 经常被人吐槽..
又不是让你通篇人肉 debug i+++i++i++++i 这种东西 一个程序员 连简单的语法糖都学不会 还学什么?弱智吗?很难吗? 满篇的啰里啰嗦破就一定好读?易维护??看得清楚???? 无非就是给自己喜欢待在舒适区 找一个理由罢了 |
66
sagaxu 2017-06-12 13:40:47 +08:00
@wangxiaoer IDE 提示补全那都是静态类型的功劳,哪个静态类型语言的 IDE 没这个功能?这跟语法糖没什么关系。
你觉得 Python 不统一,那是因为你没系统的学过它,如果学过,就该知道所有的取长度的都是 len,不管是字符串还是字节序列,列表还是字典,只要是长度就是 len,相当统一,这点还被 go 语言借鉴了去。你是在 thinking in java,不是在 thinking in python。 实际上 Python 设计的非常简单和一致,但是这种简单只有学过 Python 的人才能感受到,不是精通 XX 语言就顺便附带着懂 Python 了。 |
67
wangxiaoer 2017-06-12 14:00:47 +08:00
@sagaxu 我没说我懂 python。你根本没有明白我在说什么,长度是 len(s)不错,可是去除空字符呢 s.strip(),如果不是查阅 api,我可能会觉得是"strip(s)"。
再举个例子,数组合并成字符串,根据开发 js java 的经验,直觉告诉我可能是 ary.join("") ,实际是','.join(s),好吧我认了,分割字符串,我想套路差不多吧,python 不走寻常路,那可能是",".split(s)吧,结果真正的分割是 s.spilt(),我能怎么办,我也很无奈啊。 |
68
sagaxu 2017-06-12 15:12:13 +08:00
@wangxiaoer 那是因为不知道__len__, __iter__, __init__等 magic 方法对于 python 的意义,所以你才会觉得 len 跟 strip 有可比性,才会以为有 strip(s)这样的东西存在,只有极其普遍和通用的方法,才有可能做到 built in 里去。你能告诉我 set/list/dict 等类型的 strip,应该如何定义吗?
Java 的 join 是 String 类型的静态方法,String::join(a, list) 对应 python 的 a.join(list) Java 的 split 是 String 上的实例方法,所以 s.split()对应 python 的 s.split() 把 join 定义在 array 上的是 js,不是 java,跟 java 不一致的是 js,不是 python。 你无法下手 Python,这个锅 Python 不背。 |