Scala 是 Scalable Language 的简写,是一门多范式(编程的方式)的编程语言
Scala是一门以java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言。
Scala 是一门多范式 (multi-paradigm) 的编程语言,Scala支持面向对象和函数式编程
Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接。
Scala 单作为一门语言来看, 非常的简洁高效
终端中输入“scala”命令打开scala解释器(REPL--Read-Eval-Print-Loop)
scala命令行窗口,我们称之为REPL,也称之为交互式解释器。
说明
在命令行窗口中输入scala指令代码时,解释器会读取指令代码 并计算对应的值,然后将结果打印出来(P),接着循环等待用户输入指令。从技术上讲,这里其实并不是一个解释器,而是指令代码被快速的编译成Java字节码并被JVM加载执行。最终将执行结果输出到命令行中
Scala是一门以java虚拟机(JVM)为运行环境
①先编译完scalac Hello.scala 再执行 scala Hello ②边编译边执行 scala Hello.scala //这种方式会有点慢,每次都要进行编译 解释型(效率低)边编译边执行直接
object TestScala { // scala程序的入口依然是main方法 // scala中声明方法或函数,需要使用def关键字 // scala中声明的方法默认的访问权限就是public,所以可以省略 // scala是完全面向对象的语言,所以没有静态语法,没有static关键字 // scala采用Unit对象代替void // java是强类型语言,把类的类型写在前边声明;scala可以推断,看重变量、类的名称,它把变量args写前边; // scala中用中括号表示泛型 def main(args: Array[String]): Unit = { printf("Hello scala") } }
static跟类型 对象相关
由于Scala是完全面向对象的语言,所以是,没有静态语法且没有static关键字的,那么如果想要模拟Java中的静态语法操作,该怎么办呢?
反编译,两个.class文件(两个类)是模仿静态语法,在编译之后有静态static
$ 内部类
Hello.class
import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\001\025:Q!\001\002\t\002\025\tQ\001S3mY>T\021aA\001\by\025l\007\017^=?\007\001\001\"AB\004\016\003\t1Q\001\003\002\t\002%\021Q\001S3mY>\034\"a\002\006\021\005-qQ\"\001\007\013\0035\tQa]2bY\006L!a\004\007\003\r\005s\027PU3g\021\025\tr\001\"\001\023\003\031a\024N\\5u}Q\tQ\001C\003\025\017\021\005Q#\001\003nC&tGC\001\f\032!\tYq#\003\002\031\031\t!QK\\5u\021\025Q2\0031\001\034\003\021\t‘O]:\021\007-ab$\003\002\036\031\t)\021I\035:bsB\021qD\t\b\003\027\001J!!\t\007\002\rA\023X\rZ3g\023\t\031CE\001\004TiJLgn\032\006\003C1\001") public final class Hello{ public static void main(String[] paramArrayOfString){ Hello$.MODULE$.main(paramArrayOfString); } }
Hello$.MODULE$(它是静态的,没有值); 对象.main,而对象是空,空指针?不会,因为static静态代码块,在加载类时就new(),调用它的 构造方法-(private Hello$() { MODULE$ = this; })--是私有的,(单例模式),给MODULE$ = this即Hello$赋值了不为空,对象.main方法就不为空了; 所以Hello$.class中的main方法就不是静态的了,而是成员方法,在这个方法里printf("Hello World!") MODULE是scala自带的类; scala采用特殊的方法模拟静态访问功能 scala编译类的时候会产生2个类文件,一个是原始类文件,还有一个伴生对象类文件(内部类文件) 如果想要实现静态功能,就必须将静态功能放置在object(伴生对象即例子中的Hello$.class)中; object ->静态可以直接. 方法的提供者和方法的调用者 Object的伴生对象模拟的静态,写成class就不是静态的了;
Hello$.class
import scala.Predef$; public final class Hello${ public static final MODULE$; static{ new (); } public void main(String[] arrs){ Predef$.MODULE$.printf("Hello World!"); } private Hello$() { MODULE$ = this; } }
scala采用了一个伴生对象的概念来实现这个功能。就是说Scala在编译某个类时,不仅仅会生成这个类的字节码文件,
同时,还会生成这个类的关联对象的类文件,我们将这个关联对象称之为这个类的伴生对象(伴随类产生的对象)。
而伴生对象在加载时就自动创建了对象,所以为了模拟静态调用效果,可以将方法声明在伴生对象中,
那么这样在调用方法时,直接通过伴生对象就可以直接调用了,就好像静态调用的效果一样。
对比java中
①父子类,内部类
②权限问题
③Object中方法: native委托本地化语言去clone复制(内存中的)对象用
④final,finally,finalize的区别?https://www.cnblogs.com/shengyang17/p/10031596.html
⑤Java中方法重写是基于JVM的动态绑定技术--->模板方法设计模式 https://www.cnblogs.com/shengyang17/p/10010418.html
⑥调用一个为空(null)对象的成员属性或成员方法,-->空指针
static,scala没有静态语法,没有这个关键字
它是完全面向对象的
⑦java可以声明局部变量而不进行初始化
而scala不可以;
LocalVariableTable 本地栈变量表,压栈时给每一个变量一个局部变量表LocalVariableTable;
没有s变量,没有初始化只是声明了,它根本不会出现了这里边;java要求变量在使用前必须初始化;
scala中认为你写了就会有用;
var | val 变量名 [: 变量类型] = 变量值 #[]表示可加可不加
注意事项
声明变量时,类型可以省略(就是叫 类型自动推断功能)如var s = "ABC" 也可以写上类型var s1 : String = "ABC"
类型确定后,就不能修改,说明Scala 是强数据类型语言
在声明/定义一个变量时,可以使用var 或者 val 来修饰, var 修饰的变量可改变,val 修饰的变量不可改
val修饰的对象属性在编译后,等同于加上final
%d数字 digit %f %.2f 四舍五入
字符串通过+号连接(类似java) println("name=" + name + " age=" + age + " url=" + url) printf用法 (类似C语言)字符串通过 % 传值。(格式化输出) printf("Hello %s \n", "World!") printf("Hello %s %d %.2f \n", "alex",2, 3.145) 字符串插值打印:通过$引用(类似PHP) println(s"name=$name, age=$age, url=$url") println(s"${name.length}") ---> 4 只是用而不做其他操作可去掉{}
Scala 与 Java有着相同的数据类型,在Scala中数据类型都是对象,也就是说scala没有java中的原生(基本)类型
Scala数据类型分为两大类 AnyVal(值类型) 和 AnyRef(引用类型), 注意:不管是AnyVal还是AnyRef 都是对象。
相对于java的类型系统,scala要复杂些!也正是这复杂多变的类型系统才让面向对象编程和函数式编程完美的融合在了一起
for循环
// TODO : scala中的循环方式和java不太相同 // TODO : scala的for循环其实是对范围对象(Range)进行循环 // TODO : 范围对象可以传递三个参数:start, end, step // TODO : 范围对象(Range)是不包含end的 // TODO : scala中的循环可以使用to(包含end),until(不包含end)关键字 for (i <- 1 to 3){ //println(i) //1 2 3 } //println("##################") for (j <- 1 until 3){ //println(j) //1 2 } //println("##################") for (i <- Range(2, 10, 2)){ //println(i) //2 4 6 8 }
// 杨辉三角 // 九层妖塔 /* * *** ***** */ // TODO : Scala可以一个表达式中声明多行语句,为了理解方便,将小括号变成花括号 /* for ( i <- Range(1, 18, 2); j = (18-i)/2 ){ println(" "*j + "*"* i + " "*j) }*/ for { i <- Range(1, 18, 2) j = (18-i)/2 jj = (18-i)/2}{ println(" "*j + "*"* i + " "*jj) } * *** ***** ******* ********* *********** ************* *************** *****************
循环增加守卫条件
//可以对循环增加守卫条件,只有当条件成立,才能执行循环体,类似于continue,所以scala中没有continue关键字 for (i <-1 to 10 if i > 5){ println(i) } //scala中的循环有break操作,但是不是以关键字形式出现。以方法调用的形式出现
原文:https://www.cnblogs.com/shengyang17/p/10610624.html