动态类型
Java 是静态类型语言,不支持动态类型。不过 JVM 是支持动态类型的,Java的lambda表达式底层是用动态类型实现。
函数柯里化(curry)
又叫做部分求值,比如 sum(a, b),可以写作 sum(a)(b), sum(a) 返回一个方法,参数是 b。
惰性求值
指表达式不在它被绑定到变量之后就立即求值,而是在使用该变量时再求值。如Haskell语言。
元组
比如 Golang、Python,可以实现多返回值和交换值。
切片
可以方便的操作列表,比如Golang、Python。
指针
Java 不能直接操作指针。
多重继承
c++的多重继承实现非常复杂,子类对象转换为非第一继承的父类对象时,需要做指针偏移,而Java是自动管理内存的,实现起来更复杂。 所以Java接口可以添加static方法、static属性、函数默认实现,但是不会添加非static属性,因为有非static属性就是多重继承了。
协程
Java 层面不支持协程,有计划支持,详见 Loom Project:
Loom Wiki
消息通道
比如Golang的channel。同样在 Loom Project 中有计划支持:
Loom: Further Work
Java的 BlockingQueue 可以作为消息通道使用,不过有一定局限性,以上链接有阐述。
基本数据类型的泛型
Java 泛型是类型擦出实现,不支持基本类型。有计划支持,详见 Valhalla Project:
Valhalla Wiki
生成器
比如 Python 的 yield 实现的生成器,java 不支持类似语法。而F#中的计算表达式是一种更通用的概念。
尾递归优化
简单来说就是递归时栈空间不会增长。
默认参数、可选参数、命名参数
比如以下函数,p2 和 p3 有默认值,调用时可以不传。
调用时可以指定参数名,且可以不同于声明顺序。
int fun(string p1, int p2 = 0, int p3 = 0) {...}
fun(p2 = 5, p1 = "hello")
默认参数和方法重载有二义性问题,而且c++那样的默认参数会破坏多态。
操作符重载
Java 不支持操作符重载。
混入继承
动态语言特有的,遍历一个对象的属性和方法,将其拷贝到另一个对象上。
函数作为第一类对象
第一类对象指可以在执行期创造并作为参数传递给其他函数或存入一个变量的实体。Python的函数即为第一类对象。
动态多重分派
Java的多态仅根据对象类型进行函数分派,称为单分派,如果运行时同时根据对象类型和多个参数类型进行分派,则称为多重分派。c#的dynamic类型可以实现动态多重分派,可用于替代访问者模式。