转载

Scala 2.12 拥抱 Java 8

在今年(2015)的旧金山的ScalaDays会议上,来自Scala核心团队的Lukas Rytz分享了一个演讲: The JVM Backend and Optimizer in Scala 2.12 的技术细节,主要基于Java 8平台上一些改变, 比如Lambda, 缺省方法等。第二部分主要介绍了生成的字节码的优化。

本文是对第一部分做的笔记。

因为2.12还没有正式发布,一下特性可能还无法校验。

函数互操作 (Interop for functions: source and bytecode )

Scala 2.12只能运行在Java 8上。

Scala和Java8实现互操作。

在Scala代码中,可以使用 => 表达式应用在Java Lambda表达式的位置。

//Scala code

new Thread(() => println( "running" )).start

在Java代码中,可以使用Lamabda表达式作为函数对象应用在 => 表达式的位置:

//Java code

scalaCollection.foreach(x-> println(x))

这样Scala和Java Lambda表达式实现了互操作。

之所以能这样替换,是因为Scala 2.12将lambda表达式编译的字节码和Java的字节码是一致的,而不是匿名函数的方式。

因此在Scala代码中,函数式接口(Functional interfaces,也叫SAM)都可以通过Scala的 => 实现。

在看一个Java Stream中使用函数式接口SAM的例子:

// Java example:

stream.filter(s -> s.startsWith( "c" ))

.map(String::toUpperCase)

.sorted()

.forEach(System.out::println);

在Scala中代码中我们使用 => 实现这些SAM:

// Scala

import java.util.stream.Stream

var s = Stream of ( "a1" , "a2" , "b1" , "c2" , "c1" )

s.filter(s => s.startsWith( "c" ))

.map(_.toUpperCase).sorted.forEach(println)

毫无违和感。

Java中使用Scala类库时遇到SAM时:

在Scala 2.12中, FunctionN 是函数式接口:

// Java code:

scalaCollection.foreach(x -> println(x));

在Scala 2.11中,要使用兼容包, JFunctionN 是函数式接口。

// Java code:

import static scala.compat.java8.JFunction.*;

scalaCollection.foreach(func(x -> println(x)));

编译Trait时使用缺省方法 (Make use of default methods )

比如下面一个trait:

trait F1 {

def apply

def add(x:Int, y:Int) = x+y

}

会被编译成两个类:

public abstract interface F1

{

public abstract void apply ();

public abstract int add ( int paramInt1, int paramInt2);

}

public abstract class F1 $ class

{

public static int add (F1 $ this , int x, int y)

{

return x + y;

}

public static void $init$(F1 $ this )

{

}

}

有几种方案来编译成SAM。一种就是

public interface F1

{

public abstract void apply ();

public default int add ( int paramInt1, int paramInt2) {

return F1$class.add(paramInt1, paramInt2)

}

}

或者直接编译成SAM,不需要一个辅助类 F1$class

可以关注Scala 2.12正式发布后的实现方式。

正文到此结束
Loading...