当前位置:K88软件开发文章中心编程语言SQLscala → 文章内容

Java 与 Scala

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-19 4:45:35

由 Shaodengdeng 创建, 最后一次修改 2016-08-12 Java 与 ScalaJavapjavap 的是 JDK 附带的一个工具。不是 JRE,这里是有区别的。javap 反编译类定义,给你展示里面有什么。用法很简单[local ~/projects/interop/target/scala_2.8.1/classes/com/twitter/interop]$ javap MyTraitCompiled from "Scalaisms.scala"public interface com.twitter.interop.MyTrait extends scala.ScalaObject{ public abstract java.lang.String traitName(); public abstract java.lang.String upperTraitName();}如果你是底层控可以看看字节码[local ~/projects/interop/target/scala_2.8.1/classes/com/twitter/interop]$ javap -c MyTrait\$classCompiled from "Scalaisms.scala"public abstract class com.twitter.interop.MyTrait$class extends java.lang.Object{public static java.lang.String upperTraitName(com.twitter.interop.MyTrait); Code: 0: aload_0 1: invokeinterface #12, 1; //InterfaceMethod com/twitter/interop/MyTrait.traitName:()Ljava/lang/String; 6: invokevirtual #17; //Method java/lang/String.toUpperCase:()Ljava/lang/String; 9: areturnpublic static void $init$(com.twitter.interop.MyTrait); Code: 0: return}如果你搞不清为什么程序在 Java 上不起作用,就用 javap 看看吧!类在 Java 中使用 Scala 类 时要考虑的四个要点类参数类常量类变量异常我们将构建一个简单的 Scala 类来展示这一系列实体package com.twitter.interopimport java.io.IOExceptionimport scala.throwsimport scala.reflect.{BeanProperty, BooleanBeanProperty}class SimpleClass(name: String, val acc: String, @BeanProperty var mutable: String) { val foo = "foo" var bar = "bar" @BeanProperty val fooBean = "foobean" @BeanProperty var barBean = "barbean" @BooleanBeanProperty var awesome = true def dangerFoo() = { throw new IOException("SURPRISE!") } @throws(classOf[IOException]) def dangerBar() = { throw new IOException("NO SURPRISE!") }}类参数默认情况下,类参数都是有效的 Java 构造函数的参数。这意味着你不能从类的外部访问。声明一个类参数为 val/var 和这段代码是相同的class SimpleClass(acc_: String) { val acc = acc_}这使得它在 Java 代码中就像其他常量一样可以被访问类常量常量(val)在 Java 中定义了一个获取方法。你可以通过方法“foo()”访问“val foo”的值类变量变量(var)会生成一个 _$eq 方法。你可以这样调用它foo$_eq("newfoo");BeanProperty你可以通过 @BeanProperty 注解 val 和 var 定义。这会按照 POJO 定义生成 getter/setter 方法。如果你想生成 isFoo 方法,使用 BooleanBeanProperty 注解。丑陋的 foo$_eq 将变为setFoo("newfoo");getFoo();异常Scala 没有像 Java 那样有受检异常(checked exception)。需不需要受检异常是一个我们不会进入的哲学辩论,不过当你需要在Java中捕获它时就 很重要 了。dangerFoo 和 dangerBar 将演示这一点。在 Java 中不能这样做 // exception erasure! try { s.dangerFoo(); } catch (IOException e) { // UGLY }Java 会抱怨说 s.dangerFoo 从未抛出过 IOException 异常。我们可以通过捕获 Throwable 来跳过,但是这样不好。相反,作为一个良好的 Scala 公民,可以很体面地像在 dangerBar 中那样使用 throws 注解。这使我们能够继续在 Java 中使用受检异常。进一步阅读支持 Java 互操作的 Scala 注解的完整列表在这里 http://www.scala-lang.org/node/106。特质你如何获得一个接口+实现?让我们看一个简单的特质定义trait MyTrait { def traitName:String def upperTraitName = traitName.toUpperCase}这个特质有一个抽象方法(traitName)和一个实现的方法(upperTraitName)。Scala 为我们生成了什么呢?一个名为 MyTrait 的的接口,和一个名为 MyTrait$class 的实现类。MyTrait 和你期望的一样[local ~/projects/interop/target/scala_2.8.1/classes/com/twitter/interop]$ javap MyTraitCompiled from "Scalaisms.scala"public interface com.twitter.interop.MyTrait extends scala.ScalaObject{ public abstract java.lang.String traitName(); public abstract java.lang.String upperTraitName();}MyTrait$class 更有趣[local ~/projects/interop/target/scala_2.8.1/classes/com/twitter/interop]$ javap MyTrait\$classCompiled from "Scalaisms.scala"public abstract class com.twitter.interop.MyTrait$class extends java.lang.Object{ public static java.lang.String upperTraitName(com.twitter.interop.MyTrait); public static void $init$(com.twitter.interop.MyTrait);}MyTrait$class 只有以 MyTrait 实例为参数的静态方法。这给了我们一个如何在 Java 中来扩展一个特质的提示。首先尝试下面的操作package com.twitter.interop;public class JTraitImpl implements MyTrait { private String name = null; public JTraitImpl(String name) { this.name = name; } public String traitName() { return name; }}我们会得到以下错误[info] Compiling main sources...[error] /Users/mmcbride/projects/interop/src/main/java/com/twitter/interop/JTraitImpl.java:3: com.twitter.interop.JTraitImpl is not abstract and does not override abstract method upperTraitName() in com.twitter.interop.MyTrait[error] public class JTraitImpl implements MyTrait {[error] ^我们 可以 自己实现。但有一个鬼鬼祟祟的方式。package com.twitter.interop; public String upperTraitName() { return MyTrait$class.upperTraitName(this); }我们只要把调用代理到生成的 Scala 实现上就可以了。如果愿意我们也可以覆盖它。单例对象单例对象是 Scala 实现静态方法

[1] [2]  下一页


Java 与 Scala