1. scala編譯後的文件是以什麼結尾
scala編譯後的文件是以.class結尾。
開頭包含類似package聲明的scala代碼直接在scala命令行用:load指令載入會出錯。如果在scala命令行想調用自己在ide寫好的類時(大多數情況下你的類會用到外部包,比如spark之類的),有三種方法:
將你在ide寫好的project在scala下進行編譯,之後通過Main調用。
打包整個項目為jar,通過scala -classpath載入後,在scala中import進行調用。
去掉package聲明,並且將依賴包通過scala -classpath載入後,再使用:load 載入你的內容。
2. 大家都用什麼scala開發工具
現在的比較流行的scala開發工具都是以前的java IDE添加插件來實現的,比如IntelliJ IDEA或者Eclipse或者NetBean, 我平時用的最多的還是Intellij的,感覺用起來比較舒服,Bug比較少一點,Eclipse的問題還是太多,很多時候會出現莫名其妙的編譯錯誤,但是Eclipse好像是有個scala的官方團隊在進行開發,畢竟之前做java開發還是用eclipse的時候多。希望以後eclipse的插件能夠更完善吧,2.8.0final之後scala的eclipse插件已經更新到最新版本了,但是Intellij的插件不用更新就能直接用2.8的scala,感覺還是很舒服的,specs和scalatest都能良好運行。
3. java反編譯後是scala嗎
javap是JDK提供的一個反編譯工具。常用的選項有-c -l -s。如果僅僅是想查看編譯的得到的位元組碼文件中函數與變數,不需要帶選項。使用javap很容易發現源文件與編譯後得到的位元組碼文件有什麼不同,可以加深對編譯器的理解。
javap -help
Usage: javap <options> <classes>...
where options include:
-c Disassemble the code
-classpath <pathlist> Specify where to find user class files
-extdirs <dirs> Override location of installed extensions
-help Print this usage message
-J<flag> Pass <flag> directly to the runtime system
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes and members (default)
-private Show all classes and members
-s Print internal type signatures
-bootclasspath <pathlist> Override location of class files loaded by the bootstrap class loader
-verbose Print stack size, number of locals and args for methods If verifying, print reasons for failure
Scala是基於JVM的,所有其位元組碼和Java編譯得到的位元組碼應該是一致的。首先從Hello World開始
object Main {
def main(args: Array[String]) = {
println("Hello, " + args(0))
}
}
使用scalac編譯都得到兩個位元組碼文件:Main.class和Main$.class。
在class文件所在的目錄分別運行javap Main和javap Main$得到如下結果:
Compiled from "Main.scala"
public final class Main extends java.lang.Object{
public static final void main(java.lang.String[]);
}
Compiled from "Main.scala"
public final class Main$ extends java.lang.Object implements scala.ScalaObject{
public static final Main$ MODULE$;
public static {};
public void main(java.lang.String[]);
}
Scala的object是單例模式。上面的反編譯結果給了我們Scala實現原理的提示。MODULE$指向類的實例,相當於this。而方法也是被聲明為靜態的。做了一個測試,更加直觀。http://stackoverflow.com/questions/2347107/what-is-scala-equivalent-of-javas-static-block說如果不是去發射火箭,Object的代碼跟Java的靜態代碼可以認為是等價的。
把上面的代碼稍作修改:
case class Main {
def main(args: Array[String]) = {
println("Hello, " + args(0))
}
}
在class文件所在的目錄分別運行javap Main和javap Main$得到如下結果:
Compiled from "Main.scala"
public class Main extends java.lang.Object implements scala.ScalaObject,scala.Proct,scala.Serializable{
public scala.collection.Iterator proctIterator();
public scala.collection.Iterator proctElements();
public void main(java.lang.String[]);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public java.lang.String proctPrefix();
public int proctArity();
public java.lang.Object proctElement(int);
public boolean canEqual(java.lang.Object);
public Main();
}
Compiled from "Main.scala"
public final class Main$ extends scala.runtime.AbstractFunction0 implements scala.ScalaObject,scala.Serializable{
public static final Main$ MODULE$;
public static {};
public final java.lang.String toString();
public boolean unapply(Main);
public Main apply();
public java.lang.Object readResolve();
public java.lang.Object apply();
}
與輸入的文件相比,Scala添加了許多東西:
1. Scala自動幫助Case類生成toString, equals,hashCode等方法。
2. Scala自動幫助Case類生成apply方法,不需要new就可以直接創建類的實例或引用。
3. 對於類的成員,Scala自動生成成員的Getter和Setter。
4. Case類提供對模式匹配的支持。
下面來看Scala對類和隱式轉換的處理,有一個Rational類:
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def +(that: Rational): Rational =
new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
def +(i: Int): Rational = new Rational(numer + i * denom, denom)
def -(that: Rational): Rational =
new Rational(numer * that.denom - that.numer * denom, denom * that.denom)
def -(i: Int): Rational = new Rational(numer - i * denom, denom)
def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)
def *(i: Int): Rational = new Rational(numer * i, denom)
def /(that: Rational): Rational = new Rational(numer * that.denom, denom * that.numer)
def /(i: Int): Rational = new Rational(numer, denom * i)
override def toString = numer + "/" + denom
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
object Rational{
implicit def intToRational(x: Int) = new Rational(x)
}
javap得到:
Compiled from "Rational.scala"
public class Rational extends java.lang.Object implements scala.ScalaObject{
public static final Rational intToRational(int);
public int numer();
public int denom();
public Rational(int);
public Rational $plus(Rational);
public Rational $plus(int);
public Rational $minus(Rational);
public Rational $minus(int);
public Rational $times(Rational);
public Rational $times(int);
public Rational $div(Rational);
public Rational $div(int);
public java.lang.String toString();
public Rational(int, int);
}
Compiled from "Rational.scala"
public final class Rational$ extends java.lang.Object implements scala.ScalaObje
ct{
public static final Rational$ MODULE$;
public static {};
public Rational intToRational(int);
}
對於普通類,Scala自動添加的東西稍微少一些。一直出現的還有一個特別的函數:public static {};通過帶參數-c的javap可以看到其匯編代碼:
public static {};
Code:
0: new #9; //class Rational$
3: invokespecial #12; //Method "<init>":()V
6: return
new創建一個對象並將其引用值壓入棧頂,invokespecial調用父類的構造方法,return從當前方法返回void。該方法實際上就是一個創建自身的靜態方法。Java虛擬機指令參考http://blog.csdn.net/noonlyandroid/article/details/6117470
Rational$中的intToRational是我們提供的隱式類型轉換,將一個Int轉換為Rational。其匯編代碼如下:
public Rational intToRational(int);
Code:
0: new #16; //class Rational
3: p
4: iload_1
5: invokespecial #20; //Method Rational."<init>":(I)V
8: areturn
new首先創建一個Rational對象並將其引用值壓入棧頂,p復制棧頂數值並將復制值壓入棧頂,iload_1將第二個int型本地變數推送至棧頂,invokespecial調用Rational的構造方法,最後areturn從當前方法返回對象引用。
我們用如下代碼來測試隱式類型轉換:
import Rational._
object RationalTest {
def main(args: Array[String]) {
val r = new Rational(2,3)
println(2 * r)
}
}
2 * r本身不合法的,因為Int不存在*(Rational)的方法,由於隱式轉換的存在,Scala將做一些轉換工作。上面程序的匯編代碼如下:
Compiled from "RationalTest.scala"
public final class RationalTest$ extends java.lang.Object implements scala.Scala
Object{
public static final RationalTest$ MODULE$;
public static {};
Code:
0: new #9; //class RationalTest$
3: invokespecial #12; //Method "<init>":()V
6: return
public void main(java.lang.String[]);
Code:
0: new #16; //class Rational
3: p
4: iconst_2
5: iconst_3
6: invokespecial #20; //Method Rational."<init>":(II)V
9: astore_2
10: getstatic #25; //Field Rational$.MODULE$:LRational$;
13: iconst_2
14: invokevirtual #29; //Method Rational$.intToRational:(I)LRational;
17: aload_2
18: invokevirtual #33; //Method Rational.$times:(LRational;)LRational;
21: astore_3
22: getstatic #38; //Field scala/Console$.MODULE$:Lscala/Console$;
25: aload_3
26: invokevirtual #42; //Method scala/Console$.println:(Ljava/lang/Object;
)V
29: return
}
在做乘法($times)之前調用了 intToRational,返回一個Rational對象, 調用Rational對象的*方法已經合法化了。
4. scala 編譯完生成兩個class文件有何不同
有$符的里邊是伴生對象的內容(靜態),沒$符的里邊是類定義的內容(成員)
5. scala命令是怎麼編譯運行scala程序的
scala命令是怎麼編譯運行scala程序的
所以既要使用到Unicode的大的字型檔表,又要節省存儲空間,就需要對Unicode再編碼,且是根據(Unicode編碼.n)內容 不定長編碼 --- UTF-8是一種對(Unicode編碼.n)的不定長字元編碼方案。
UTF-8字元編碼方案決定了(Unicode編碼.n)在計算機內的存儲方式。
(Unicode編碼.n)經過UTF-8字元編碼方案編碼之後也可以看做是一個新的二進制數字,(通常用十六進制數字字元表示這個新的二進制的值,它們直接的關系是這個十六進制字元表示的值 等於 這個二進制數字的值)。
6. scala是編程語言還是腳本語言
按傳統,程序語言分編譯語言和解釋語言。編譯語言要把源程序編譯成2進制可執行程序再運行。而解釋性語言,即所謂腳本語言,不需預先編譯,而可在解釋器的解釋下,直接解釋執行。
我不熟悉scala,看上去scala像似 是一種封裝式的東西,例如,封裝的 java 式的東西 要編譯成 bytecode 後執行。 類似 ruby, python 之類的東西也許可以解釋執行。scala 好像沒有自己的虛擬機,對 scala 的爭論 不少。
7. Eclipse中如何實現scala開發環境的構建
1)新建一個目錄叫 test
2)在test目錄中新建文件build.sbt
3)在test目錄新建project目錄,進入project目錄,並新建plugins.sbt,在其中添加
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0")
4)在build.sbt中配置工程的name,scala編譯環境,依賴等等。如:
import sbt._
import Process._
import Keys._
EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource
lazy val commonSettings = Seq(
name := "test",
organization := "com.marsyoung",
version := "0.0.1-SNAPSHOT",
scalaVersion := "2.11.7"
)
lazy val root = (project in file(".")).
settings(commonSettings: _*).
settings(
libraryDependencies ++= Seq(
"junit" % "junit" % "4.4",
"javax.ws.rs" % "jsr311-api" % "1.1.1"
)
)
5)在cmd中進入對應的project目錄,即test目錄。運行sbt。
6)執行eclipse命令,將對應的項目轉化成可以引入eclipse開發工具並且目錄結構類似maven的項目。
7)打開已經安裝了scala ide的eclipse,導入對應的project,會自動的編譯成scala peoject.