如约而至,Java 10 正式发布:包含 109 项新特性

oschina
 oschina
发布于 2018年03月21日
收藏 41

期待已久,没有跳票的 Java 10 已正式发布!你可以通过这里下载 Java 10 正式版

此前我们曾报道过,为了更快地迭代,以及跟进社区反馈,Java 的版本发布周期变更为每六个月一次,并且承诺不会跳票。新的发布周期也会严格遵循时间点,将在每年的 3 月份和 9 月份发布。所以 Java 10 的版本号是 18.3。

Java 10 是采用新发布周期的第一个版本,提供了 109 项新特性,其中最备受关注的莫过于局部变量的类型推断。

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

这样的 Java 代码你喜欢吗?

相关链接:

其他链接:

Java 10 的 12 项关键新特性:

  • JEP 286: 局部变量的类型推断。该特性在社区讨论了很久并做了调查,可查看 JEP 286 调查结果

  • JEP 296: 将 JDK 的多个代码仓库合并到一个储存库中

  • JEP 304: 垃圾收集器接口。通过引入一个干净的垃圾收集器(GC)接口,改善不同垃圾收集器的源码隔离性。

  • JEP 307: 向 G1 引入并行 Full GC

  • JEP 310: 应用类数据共享。为改善启动和占用空间,在现有的类数据共享(“CDS”)功能上再次拓展,以允许应用类放置在共享存档中

  • JEP 312: 线程局部管控。允许停止单个线程,而不是只能启用或停止所有线程

  • JEP 313: 移除 Native-Header Generation Tool (javah)

  • JEP 314: 额外的 Unicode 语言标签扩展。包括:cu (货币类型)、fw (每周第一天为星期几)、rg (区域覆盖)、tz (时区) 等

  • JEP 316: 在备用内存设备上分配堆内存。允许 HotSpot 虚拟机在备用内存设备上分配 Java 对象堆

  • JEP 317: 基于 Java 的 JIT 编译器(试验版本)

  • JEP 319: 根证书。开源 Java SE Root CA 程序中的根证书

  • JEP 322: 基于时间的版本发布模式。“Feature releases” 版本将包含新特性,“Update releases” 版本仅修复 Bug

JDK 10 正式版下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net]
本文标题:如约而至,Java 10 正式发布:包含 109 项新特性
加载中

精彩评论

GDIKodiak
GDIKodiak
Java11添加自动属性 get; set;
Java12添加线程包装类Task
Java13添加异步语法async await
Java14添加协程
Java15添加let
……
反正都要抄了就顺着抄一遍吧(滑稽)
红薯
红薯
@巴拉迪维 oschina 是不是考虑升级到 java 10 啊?
黑人牙膏
黑人牙膏
靠,,下周我就要去这家公司上班了,法克了,这么搞法,越来越向弱语言靠拢,完蛋了。
我还去不去这家公司上班啊?
Zac_49
Zac_49
用JDK7的来报到
苍耳道人
苍耳道人
这是要玩死java的节奏……

最新评论(174

烟头
烟头

引用来自“黑人牙膏”的评论

靠,,下周我就要去这家公司上班了,法克了,这么搞法,越来越向弱语言靠拢,完蛋了。
我还去不去这家公司上班啊?

引用来自“一个大土豆”的评论

欢迎来甲骨文,如果做业务产品的话,还用jdk6。放心
我用1.4 稳定!
niniwei
niniwei
感觉最水的一个版本,这是要把java往火坑里带😆
yong9981
yong9981
Re: dwing0:现在可以这样写, 虽然多一行, 但不影响重构:
public static final String C_UID = "user_id";
@Column(C_UID)
private String uid;
ctx.query("select * from users where ", User.C_UID, "=?", param0("123"));
这种做法我已经在采用,在jSqlBox的用户手册中有这么个支持重构的SQL示例,见https://gitee.com/drinkjava2/jSqlBox/wikis的iXxxx内嵌参数一节:
ctx.iExecute("insert into ", User.Table, " ( ", //Table、NAME等是在User类中定义的字符串常量
User.NAME, ",", param0("Sam"), //
User.ADDRESS, " ", param("Canada"), //
") ", valuesQuesions());
但它的问题是不优雅,有两个问题:
1)凭什么要多写一行? 架构师和语言开发者干什么去了? 如果一个类中有50个属性,采用这种风格就要多写50行这种多余的垃圾代码,语言应该服务于开发者而不是开发者迁就语言。对于一个有洁僻的程序员来说很讨厌这种坏味道的。Java因为getter和setter的设计,只好用IDE功能自动生成getter/setter,缓解了一下痛苦,这多出来的50行垃圾代码, 是不是又要发明一个IDE自动生成功能插件,就算发明了这个插件,这多出来的50行代码也是大大的一堆翔堆在源码里。
2)它只能取得字符串常量,而不是属性的名称,当属性有一大堆Annotation, 需要定位到属性上时,通常的做法是用一个包含属性名字的大写字符串常量来充当这个属性ID,当一个属性要重构时,必须手工再重构一遍这个字符串常量,还不能打错字,这又是一个很无聊的手工操作。
d
dwing0

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.

引用来自“yong9981”的评论

获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。

引用来自“dwing0”的评论

说了半天也没看出来要名字有何意义, 程序的本质是数据+算法, 叫什么名字会影响功能吗?

引用来自“yong9981”的评论

名字怎么取不重要,名字取错后是否可以通过重构来更改很重要。当使用 someMethod(类:方法名)这种调用时,无论程序中出现多少次调用,当方法名重构时,IDE会将所有出现的地方更正为新方法名。反之,当使用someMethod("方法名")这种方式时,IDE无法正确重构。过于动态的语言如JavaScript,由于过于灵活,IDE不支持方法重构,方法名一旦取错或需求变更需要改名,不能利用IDE来自动更正,所以说“动态类型一时爽,代码重构火葬场”。

引用来自“dwing0”的评论

没错, 我也是更赞成静态的, 静态的意义就在于所有的变量/函数名都只有编写和编译用途, 运行时就没有意义了.
话说回来, 通过函数参数传入的只是值, 并没有与值的来源/名字绑定, 值来自哪里, 是类成员,栈变量,计算的中间结果,甚至是匿名对象/方法, 都是可能的, 获取其名字没有什么意义, 可能仅仅是你说的想输出一行所属的名字的日志, 但这个名字有可能是匿名或临时的, 需要获取来源只能依靠stacktrace了.

引用来自“yong9981”的评论

不是的,获取变量或方法名的意义很大,不会只用来做日志这么简单的事,前面已经说了可以用来获取Annotation的值,例如,假如Java12版支持变量或方法名作为参数传递,则会有如下用法:
public Class User{
@Column("user_id")
public String uid;
...
}

主程序中
User u=new User();
ctx.query("select * from users where ", u:uid, "=?", param0("123"));
或 ctx.query("select * from users where ", User:uid, "=?", param0("123"));
最后两行是优雅的支持重构的SQL写法。query方法在获取u:uid或User:uid后,自动取得它对应的@Column值"user_id", 最后的SQL会变成这样:
select * from users where user_id=?
当User类的uid更名时,所有涉及的SQL都不变,当数据库表user_id更名为user_id2时,只要改Annotation为 @Column("user_id2"),所有涉及的SQL都会变成select * from users where user_id2=?
现在可以这样写, 虽然多一行, 但不影响重构:
  public static final String C_UID = "user_id";
  @Column(C_UID)
  private String uid;
ctx.query("select * from users where ", User.C_UID, "=?", param0("123"));
yong9981
yong9981

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.

引用来自“yong9981”的评论

获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。

引用来自“dwing0”的评论

说了半天也没看出来要名字有何意义, 程序的本质是数据+算法, 叫什么名字会影响功能吗?

引用来自“yong9981”的评论

名字怎么取不重要,名字取错后是否可以通过重构来更改很重要。当使用 someMethod(类:方法名)这种调用时,无论程序中出现多少次调用,当方法名重构时,IDE会将所有出现的地方更正为新方法名。反之,当使用someMethod("方法名")这种方式时,IDE无法正确重构。过于动态的语言如JavaScript,由于过于灵活,IDE不支持方法重构,方法名一旦取错或需求变更需要改名,不能利用IDE来自动更正,所以说“动态类型一时爽,代码重构火葬场”。

引用来自“dwing0”的评论

没错, 我也是更赞成静态的, 静态的意义就在于所有的变量/函数名都只有编写和编译用途, 运行时就没有意义了.
话说回来, 通过函数参数传入的只是值, 并没有与值的来源/名字绑定, 值来自哪里, 是类成员,栈变量,计算的中间结果,甚至是匿名对象/方法, 都是可能的, 获取其名字没有什么意义, 可能仅仅是你说的想输出一行所属的名字的日志, 但这个名字有可能是匿名或临时的, 需要获取来源只能依靠stacktrace了.
不是的,获取变量或方法名的意义很大,不会只用来做日志这么简单的事,前面已经说了可以用来获取Annotation的值,例如,假如Java12版支持变量或方法名作为参数传递,则会有如下用法:
public Class User{
@Column("user_id")
public String uid;
...
}

主程序中
User u=new User();
ctx.query("select * from users where ", u:uid, "=?", param0("123"));
或 ctx.query("select * from users where ", User:uid, "=?", param0("123"));
最后两行是优雅的支持重构的SQL写法。query方法在获取u:uid或User:uid后,自动取得它对应的@Column值"user_id", 最后的SQL会变成这样:
select * from users where user_id=?
当User类的uid更名时,所有涉及的SQL都不变,当数据库表user_id更名为user_id2时,只要改Annotation为 @Column("user_id2"),所有涉及的SQL都会变成select * from users where user_id2=?
d
dwing0

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.

引用来自“yong9981”的评论

获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。

引用来自“dwing0”的评论

说了半天也没看出来要名字有何意义, 程序的本质是数据+算法, 叫什么名字会影响功能吗?

引用来自“yong9981”的评论

名字怎么取不重要,名字取错后是否可以通过重构来更改很重要。当使用 someMethod(类:方法名)这种调用时,无论程序中出现多少次调用,当方法名重构时,IDE会将所有出现的地方更正为新方法名。反之,当使用someMethod("方法名")这种方式时,IDE无法正确重构。过于动态的语言如JavaScript,由于过于灵活,IDE不支持方法重构,方法名一旦取错或需求变更需要改名,不能利用IDE来自动更正,所以说“动态类型一时爽,代码重构火葬场”。
没错, 我也是更赞成静态的, 静态的意义就在于所有的变量/函数名都只有编写和编译用途, 运行时就没有意义了.
话说回来, 通过函数参数传入的只是值, 并没有与值的来源/名字绑定, 值来自哪里, 是类成员,栈变量,计算的中间结果,甚至是匿名对象/方法, 都是可能的, 获取其名字没有什么意义, 可能仅仅是你说的想输出一行所属的名字的日志, 但这个名字有可能是匿名或临时的, 需要获取来源只能依靠stacktrace了.
yong9981
yong9981

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.

引用来自“yong9981”的评论

获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。

引用来自“dwing0”的评论

说了半天也没看出来要名字有何意义, 程序的本质是数据+算法, 叫什么名字会影响功能吗?
名字怎么取不重要,名字取错后是否可以通过重构来更改很重要。当使用 someMethod(类:方法名)这种调用时,无论程序中出现多少次调用,当方法名重构时,IDE会将所有出现的地方更正为新方法名。反之,当使用someMethod("方法名")这种方式时,IDE无法正确重构。过于动态的语言如JavaScript,由于过于灵活,IDE不支持方法重构,方法名一旦取错或需求变更需要改名,不能利用IDE来自动更正,所以说“动态类型一时爽,代码重构火葬场”。
d
dwing0

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.

引用来自“yong9981”的评论

获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。
说了半天也没看出来要名字有何意义, 程序的本质是数据+算法, 叫什么名字会影响功能吗?
yong9981
yong9981

引用来自“yong9981”的评论

Re: dwing0 "Bean不都是个类吗, 怎么变成一个方法了? "
Spring的Java配置允许同一个类存在多种配置,用不同的方法来定义,这种情况下不能用ctx.getBean(SomeBean.class)来获取,而只能用ctx.getBean("方法名")这种原始的字符串方式。

引用来自“dwing0”的评论

这种设计本身就有不太静态, 通过方法名很容易有歧义, 因为没有指定是哪个类的方法名, 所以你抱怨不好重命名也是没办法的.
如果指定了类, 那么为什么getBean不直接接收Supplier类型, 把类::方法传进去?

引用来自“yong9981”的评论

如果一个方法是public static getBean(Supplier obj){ xxx }, 你给它传一个类::方法过去,它拿到的是一个类似"xx.xx.Lambda$1/17230114@1be5d1"的对象,方法名丢失了。要想知道方法名,必须用ASM之类工具反编译字节码,可参见Jaque项目。 这还只是针对方法,如果一个类中有一个public Interger age属性,根本就没有办法用类::age来传递变量名,Java无法做到。所以说Java真正的变革太少了,Lambda和var都是讨好编译器的语法糖而已,和弱语言还差远着呢,真正开发者需要的功能都建立在CGLib/ASM这种非正常的字节码工具上,简直是打脸。

引用来自“dwing0”的评论

依赖函数名本身在偏静态语言里都是不推荐的, 如C/C++更难获取.
因为获取这些名字没什么意义, 仅仅是为了动态性, 而动态性虽然更灵活, 但也失去了更严格的静态检查.
传方法的最终目的是为了在合适的地方执行, 获取名字不是必要的.
Java本质还是偏静态的语言, 动态特性基本都要靠反射,而且也不是很动态, 这么需要动态性而不要求静态检查和性能, 那就不应该选择Java了.
获取方法或变量的名字意义非常大,现在都流行在Java Bean的属性或方法上加一堆Annotation, 但是如何根据方法名或属性名快速取得这些Annotation就没有好办法了,只能用反射获取全部属性的Annotation或是用字符串的方式来指定某一个方法或变量名,这是非常讨厌的。一个Annotation就是一个坑,挖了坑但是但是又不能快速定位,这就是俗话说的“管杀不管埋”。
如果加上这个功能,不仅不会破坏Java静态检查的特性,而且还改善了这一点,可以利用到IDE的功能支持重构和快速定位到方法、变量上。 当然对于一些需要混淆器加密源码的场合,可以通过增加编译开关来关闭支持方法名、变量名这个功能,但通常90%情况下开发人员并不在意源码是否要混淆。
eechen
eechen

引用来自“猫之良品”的评论

抄C#也挺好的,没什么好批评,而且都应该抄快点,谁叫人家影响力大。

引用来自“eechen”的评论

静态类型语言支持局部变量类型推断,简直就是不伦不类.
还是大PHP好用,无需声明类型,也不用什么var/let,大大减低开发时的心智负担.

引用来自“飞酒”的评论

php新版本已经开始要类型了, 各种学和转

引用来自“eechen”的评论

是么?强类型strict_types是从PHP7开始引入的东西,【默认不开启】,【以后也不会默认开启】,是一个很有争议性且完全不兼容PHP5的特性.其中PHP之父Rasmus,Zend公司CEO兼创始人Andi,PHP7性能方面的核心开发者Dmitry和鸟哥Laruence都投了反对票.
https://wiki.php.net/rfc/scalar_type_hints_v5

引用来自“dwing0”的评论

php加强类型感觉跟java很像了, 这样php就失去了自己的特点和原本的设计原则, 估计很多用php的会因此改用java, 这样对php的发展可能反而不利, 所以理解投反对票的.
一点都不像,因为PHP的strict_types只检查函数参数和返回值,对于其他变量,并没有类型定义一说.
返回顶部
顶部