- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在上一个问题Accessing scala.None from Java中,人们似乎已经使用javap
来弄清楚如何从Java中访问scala.None
。我想知道他们是如何做到的。仅供引用,答案是:
scala.Option$.MODULE$.apply(null);
scala.Option.apply(null);
OptionTest.scala
):
object OptionTest extends App {
val x = scala.None
val y = scala.Some("asdf")
}
javap
:
javap -s -c -l -private OptionTest
javap
输出的一部分:
public static final scala.None$ x();
Signature: ()Lscala/None$;
Code:
0: getstatic #11; //Field OptionTest$.MODULE$:LOptionTest$;
3: invokevirtual #55; //Method OptionTest$.x:()Lscala/None$;
6: areturn
scala.None
和
scala.Option
上运行了javap。如何从
javap
输出中得出以下结论:
None
是None.type
类型的唯一对象,它扩展了Option
apply()
方法是必需的最佳答案
有规则将Scala代码编译为JVM字节码。由于潜在的名称冲突,生成的代码并不总是很直观易懂,但是如果知道规则,则可以在Java中访问已编译的Scala代码。
Attention: While writing this, I noticed that javac and eclipse-javac behave differently in accessing Scala code from Java. It is possible that the code below compile with one of them but not with the other.
class X(i: Int) {
def m1 = i*2
def m2(a: Int)(b: Int) = a*b
def m3(a: Int)(implicit b: Int) = a*b
}
X.class
的文件:
X x = new X(7);
x.m1();
x.m2(3, 5);
x.m3(3, 5);
class X(var i: Int)
类,将创建Getter和Setter。对于
class X(val i: Int)
类,仅创建一个Getter:
//Scala
val x = new X(5)
x.i = 3 // Setter
x.i // Getter
//Java
X x = new X(5);
x.i_$eq(3); // Setter
x.i(); // Getter
scala> import scala.reflect.NameTransformer._
import scala.reflect.NameTransformer._
scala> val ops = "~=<>!#%^&|*/+-:\\?@"
ops: String = ~=<>!#%^&|*/+-:\?@
scala> ops map { o => o -> encode(o.toString) } foreach println
(~,$tilde)
(=,$eq)
(<,$less)
(>,$greater)
(!,$bang)
(#,$hash)
(%,$percent)
(^,$up)
(&,$amp)
(|,$bar)
(*,$times)
(/,$div)
(+,$plus)
(-,$minus)
(:,$colon)
(\,$bslash)
(?,$qmark)
(@,$at)
class X { var i = 5 }
类的转换方式与在构造函数中创建字段时的方式相同。无法从Java直接访问变量
i
,因为它是私有(private)的。
object X { val i = 5 }
,将生成两个JVM类文件:
X.class
和
X$.class
。第一个类似于接口(interface),它包含用于访问字段和Scala对象的方法的静态方法。后者是无法实例化的单例类。它具有一个Field,该字段保存名为
MODULE$
的类的单例实例,该实例允许访问单例:
X.i();
X$.MODULE$.i();
case class X(i: Int)
易于访问:
new X(3).i();
X$.MODULE$.apply(3);
trait T { def m }
被编译为接口(interface),该接口(interface)放置在名为
T.class
的类文件中。因此,它可以通过Java类轻松实现:
class X implements T {
public void m() {
// do stuff here
}
}
<trait_name>$class.class
的类文件。特质
trait T {
def m1
def m2 = 5
}
T$class.class
包含该特征的具体成员,但似乎无法从Java访问它们。 javac和eclipse-javac都不会编译对此类的访问。
object X {
val f: Int => Int = i => i*2
def g: Int => Int = i => i*2
def h: Int => Int => Int = a => b => a*b
def i: Int => Int => Int = a => {
def j: Int => Int = b => a*b
j
}
}
<class_name>$$anonfun$<N>.class
的类文件,其中N是一个连续数字。对于函数方法(返回函数的方法),将生成一个名为
<class_name>$$anonfun$<method_name>$<N>.class
的类文件。函数名称的各部分用美元符号分隔,在
anonfun
标识符前面也有两个美元符号。对于嵌套函数,嵌套函数的名称将附加到外部函数之后,这意味着内部函数将获得一个类似
<class_name>$$anonfun$<outer_method_name>$<N>$$anonfun$<inner_method_name>$<N>.class
的类文件。当内部函数没有名称时(如
h
中所示),它将获得名称
apply
。
X$$anonfun$1.class
X$$anonfun$g$1.class
X$$anonfun$h$1$$anonfun$apply$1.class
I和J的X$$anonfun$i$1.class
和X$$anonfun$i$1$$anonfun$j$1$1.class
X.f().apply(7);
X.g().apply(7);
X.h().apply(3).apply(5);
X.i().apply(3).apply(5);
MODULE$
字段// javap scala.Option
public abstract class scala.Option extends java.lang.Object implements ... {
...
public static final scala.Option apply(java.lang.Object);
public scala.Option();
}
Option.apply(3);
// javap scala.Some
public final class scala.Some extends scala.Option implements ... {
...
public scala.Some(java.lang.Object);
}
new Some<Integer>(3);
Some.apply(3);
// javap scala.None
public final class scala.None extends java.lang.Object{
...
}
None$
:
// javap -private scala.None$
public final class scala.None$ extends scala.Option implements ... {
...
public static final scala.None$ MODULE$;
private scala.None$();
}
MODULE$
字段和Option的apply方法。此外,我们找到了私有(private)构造函数:
None$.apply(3) // returns Some(3). Please use the apply-method of Option instead
None$.MODULE$.isDefined(); // returns false
new None$(); // compiler error. constructor not visible
scala.collection.immutable.List
是抽象的,因此我们必须使用
scala.collection.immutable.List$
。它有一个应用方法,需要
scala.collection.Seq
。因此,要获取列表,我们首先需要一个Seq。但是,如果我们看Seq,就没有适用方法。此外,当我们查看Seq的父类(super class)和
scala.collection.Seq$
时,我们只能找到一个期望Seq的应用方法。那么该怎么办?
class X {
val xs = List(1, 2, 3)
}
// javap -c -private X
public class X extends java.lang.Object implements scala.ScalaObject{
...
public X();
Code:
0: aload_0
1: invokespecial #20; //Method java/lang/Object."<init>":()V
4: aload_0
5: getstatic #26; //Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
8: getstatic #31; //Field scala/Predef$.MODULE$:Lscala/Predef$;
11: iconst_3
12: newarray int
14: dup
15: iconst_0
16: iconst_1
17: iastore
18: dup
19: iconst_1
20: iconst_2
21: iastore
22: dup
23: iconst_2
24: iconst_3
25: iastore
26: invokevirtual #35; //Method scala/Predef$.wrapIntArray:([I)Lscala/collection/mutable/WrappedArray;
29: invokevirtual #39; //Method scala/collection/immutable/List$.apply:(Lscala/collection/Seq;)Lscala/collection/immutable/List;
32: putfield #13; //Field xs:Lscala/collection/immutable/List;
35: return
}
scala.Predef$.wrapIntArray
(图26)。生成的
scala.collection.mutable.WrappedArray
再次传送到我们的列表中(图29)。最后,列表存储在字段中(图32)。
int[] arr = { 1, 2, 3 };
WrappedArray<Object> warr = Predef$.MODULE$.wrapIntArray(arr);
List$.MODULE$.apply(warr);
// or shorter
List$.MODULE$.apply(Predef$.MODULE$.wrapIntArray(new int[] { 1, 2, 3 }));
关于scala - 如何使用Java而不是Java来学习如何使用scala。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9350528/
我有一些 Scala 代码,它用两个不同版本的类型参数化函数做了一些漂亮的事情。我已经从我的应用程序中简化了很多,但最后我的代码充满了形式 w(f[Int],f[Double]) 的调用。哪里w()是
如果我在同一目录中有两个单独的未编译的 scala 文件: // hello.scala object hello { def world() = println("hello world") }
val schema = df.schema val x = df.flatMap(r => (0 until schema.length).map { idx => ((idx, r.g
环境: Play 2.3.0/Scala 2.11.1/IntelliJ 13.1 我使用 Typesafe Activator 1.2.1 用 Scala 2.11.1 创建一个新项目。项目创建好后
我只是想知道如何使用我自己的类扩展 Scala 控制台和“脚本”运行程序,以便我可以通过使用实际的 Scala 语言与其通信来实际使用我的代码?我应将 jar 放在哪里,以便无需临时配置即可从每个 S
我已经根据 README.md 文件安装了 ensime,但是,我在低级 ensime-server 缓冲区中出现以下错误: 信息: fatal error :scala.tools.nsc.Miss
我正在阅读《Scala 编程》一书。在书中,它说“一个函数文字被编译成一个类,当在运行时实例化时它是一个函数值”。并且它提到“函数值是对象,因此您可以根据需要将它们存储在变量中”。 所以我尝试检查函数
我有 hello world scala native 应用程序,想对此应用程序运行小型 scala 测试我使用通常的测试命令,但它抛出异常: NativeMain.scala object Nati
有few resources在网络上,在编写与代码模式匹配的 Scala 编译器插件方面很有指导意义,但这些对生成代码(构建符号树)没有帮助。我应该从哪里开始弄清楚如何做到这一点? (如果有比手动构建
我是 Scala 的新手。但是,我用 创建了一个中等大小的程序。斯卡拉 2.9.0 .现在我想使用一个仅适用于 的开源库斯卡拉 2.7.7 . 是吗可能 在我的 Scala 2.9.0 程序中使用这个
有没有办法在 Scala 2.11 中使用 scala-pickling? 我在 sonatype 存储库中尝试了唯一的 scala-pickling_2.11 工件,但它似乎不起作用。我收到消息:
这与命令行编译器选项无关。如何以编程方式获取代码内的 Scala 版本? 或者,Eclipse Scala 插件 v2 在哪里存储 scalac 的路径? 最佳答案 这无需访问 scala-compi
我正在阅读《Scala 编程》一书,并在第 6 章中的类 Rational 实现中遇到了一些问题。 这是我的 Rational 类的初始版本(基于本书) class Rational(numerato
我是 Scala 新手,我正在尝试开发一个使用自定义库的小项目。我在库内创建了一个mysql连接池。这是我的库的build.sbt organization := "com.learn" name :
我正在尝试运行一些 Scala 代码,只是暂时打印出“Hello”,但我希望在 SBT 项目中编译 Scala 代码之前运行 Scala 代码。我发现在 build.sbt 中有以下工作。 compi
Here链接到 maven Scala 插件使用。但没有提到它使用的究竟是什么 Scala 版本。我创建了具有以下配置的 Maven Scala 项目: org.scala-tools
我对 Scala 还很陌生,请多多包涵。我有一堆包裹在一个大数组中的 future 。 future 已经完成了查看几 TB 数据的辛勤工作,在我的应用程序结束时,我想总结上述 future 的所有结
我有一个 scala 宏,它依赖于通过包含其位置的静态字符串指定的任意 xml 文件。 def myMacro(path: String) = macro myMacroImpl def myMacr
这是我的功能: def sumOfSquaresOfOdd(in: Seq[Int]): Int = { in.filter(_%2==1).map(_*_).reduce(_+_) } 为什么我
这个问题在这里已经有了答案: Calculating the difference between two Java date instances (45 个答案) 关闭 5 年前。 所以我有一个这
我是一名优秀的程序员,十分优秀!