关于 类名.class 和 类名$.class文件
第一步:scala代码【没有main方法】
创建两个字节码文件:Test$.class 和 Test.class
Test.class : 普通不可变的类
Test$.class: ① 静态代码块(加载此类时会创建此类的对象)
② 静态属性,类型为当前类
③ 将获取的对象赋值给静态属性
object Test {
}
Test.class代码内容
package com.at;import scala.reflect.ScalaSignature;public final class Test {}
Test$.class 代码内容:
package com.at;public final class Test${
public static Test$ MODULE$; //一个静态属性 static {} //创建了当前类的一个对象 ,0: new #2 // class com/at/Test$ private Test$() { MODULE$ = this; } //私有的空参构造器,this}
使用反编译:Javap -c -l 类名可以查询
D:\01_workspace\workspace_idea\Scala\target\classes\com\>javap -c -l Test$警告: 二进制文件Test$包含com.at.Test$Compiled from "Test.scala"public final class com.Test$ {
public static com..Test$ MODULE$; public static {}; Code: 0: new #2 // class com/Test$ 3: invokespecial #12 // Method "":()V 6: return}
第二步:scala代码加入main方法
Test.class :创建了静态的main(),调用Test$.class的静态属性,返回值是Test$.class类的对象,通过对象调用Test$.class类中的普通main方法;
Test$.class :创建了一个无方法体的普通main方法
object Test {
def main(args : Array[String]) : Unit = {
}}
Test.class代码内容
package com.at;import scala.reflect.ScalaSignature;public final class Test {
public static void main(String[] paramArrayOfString) {
// 调用Test$.class的静态属性,返回值是Test$.class的对象,通过对象调用Test$.class类中的普通main方法 Test$.MODULE$.main(paramArrayOfString); }}
Test$.class代码内容
package com.at;public final class Test${
public static Test$ MODULE$; //静态属性 static {
} public void main(String[] args) {} //创建了一个普通的main方法 private Test$() { MODULE$ = this; } //给静态属性赋值,值为当前类的一个实例对象}
第三步:在scala代码中加入println()方法
Test.class:没有变化,依然是通过调用Test$.class对象.main()
Test$.class :在普通main()体内增加了scala方法体内的代码
object Test {
def main(args : Array[String]) : Unit = {
println("test"); }}
Test$.class 代码内容
package com.at;import scala.Predef$;public final class Test$ {
public static Test$ MODULE$; static {
} // 在mian方法中加入了println()代码 public void main(String[] args) { Predef$.MODULE$.println("test"); } private Test$() { MODULE$ = this; }}
总结
-- 第一步:scala代码【没有main方法】 创建两个字节码文件:Test$.class 和 Test.class 1.Test.class : 普通不可变的类 2.Test$.class : ① 静态代码块(加载此类时会创建此类的对象) ② 静态属性,类型为当前类'Test$' ③ 将获取的对象实例赋值给静态属性 -- 第二步:scala代码加入main方法 1.Test.class :创建了静态的main,调用Test$.class的静态属性,返回值是'类名$'的对象,通过对象调用Test$.class类中的main()方法; 2.Test$.class :创建了一个无方法体的main()方法 -- 第三步:在scala代码中加入println()方法 1.Test.class :没有变化,依然是通过调用Test$.class对象.main() 2.Test$.class :在main()体内增加了scala方法体内的代码 -- 总结 如果没有将scala源代码声明成object(模拟java中的静态语法),就不会生产 Test$.class文件,则不会创建 Test$类的对象,同时在scala逻辑代码也不会在体现,则此时的scala是无法执行。
2.2 代码解析
代码
object Scala01_Hello {
// public static void main(String[] args) def main(args: Array[String]): Unit = {
// 方法体 System.out.println("Hello Scala") // 打印 println("Hello Scala") }}
解析
-- 1.object1. scala语言没有静态的语法,采用object方法模仿java的静态方法,通过类名对象.方法2. scala是一个完全面对对象编程语言;3. java不是一个完全面向对象编程语言。-- 2.defdefine的缩写,声明方法或函数的关键字-- 3.agrs : Array[string] :参数说明1. scala :变量名 :数据类型java :数据类型 变量2. Array :scala的数组,相当于java中的 []3. [String] : 泛型-- 4.unitUnit(类型) <==> void(关键字) *-- 5. = :赋值,方法也是对象,可以赋值 * * Scala语言是基于java语言开发的。所以可以直接嵌入java代码执行 * * Scala语言中默认会导入一些对象,那么这些对象的方法可以直接使用 * 类似于java中import java.lang
2.3 方法解析
object Scala02_Test {
// 声明方法 def // 名称(参数列表) :类型 // 参数名:参数类型 // 方法赋值 def main( args : Array[String] ) : Unit = {
// 方法体 println("Hello Test") // 调用方法 println(Scala02_Test.test()) } def test() : String = {
return "test" }}
2.4 scala的calss类
// 使用class关键字声明的类,在编译时,只会产生一个类文件,并且不能模仿静态语法操作class Scala03_Class {
def main(args: Array[String]): Unit = {
}}
三、变量和数据类型
3.1 变量
-- 1.声明语法var/val 变量名称 : 变量类型 = 变量值-- 2.特点 1.如果可以通过语法推断出来变量类型,那么变量在声明时可以省略类型; 2.Scala是静态类型语言,在编译时必须要确定变量类型; 3.变量必须显示的初始化,不能省略; 4.var和val变量类型一旦确定以后就不能变化; 5.var声明的变量的值"可以"改变,val声明的变量的值"不可以"改变 6.val比var使用的场景更多,更广-- 3.例子: var name : String = "zhangsan" var name = "zhangsan" -->类型推断 name = "lisi" -->可变变量 val age = 10 --> 类型推断 age = 20 --> 报错,不可变变量,不能改变值 val id : Int -->报错,变量必须显式化赋值 id = 10 -- 4.说明: 整型对象默认类型:Int 浮点型对象默认类型:Double-- 5.val 和 常量的区别: "123"、"张三"、2 --> 常量 val name = "zhangsan" -->name是不可变变量,首先它是一个变量
3.2 标识符
-- 标识符规则 ,就是起名字,如给变量、类、方法、函数起名 1.Scala标识符分为字符+数字、字符两种 2.命名的规则如下: a.不能以数字开头 b.不能使用关键字和保留字 c.不限制长度 d.区分大小写 e.有很多符号也可以作为标识符-- 如何使用标识符 1.随便起,报错就换一个 2.常见用于语法操作的符号不能用: {}、“”、‘’、() ,:,[] 3.$,这个符号能不用就尽量不用 4.如果就是要使用关键字作为名字,使用"飘号"处理。 如:`private`
举例:
object Scala_Identifier {
def main(args: Array[String]): Unit = {
//调用此方法 println(:>()) //lianpeng () } //定义一个方法,方法名是 :> ,返回值类型是Unit,返回值是:() def :>(): Unit = {
println("lianpeng") }}
3.3 Scala与Java的互访问方式
//Scala访问java,直接访问,因为Scala是基于java开发 object Scala_java {
def main(args: Array[String]): Unit = {
val user = new User println(user.age) } def test () : Unit={
println("你好啊") }}
// java访问Scalapublic class test {
public static void main(String[] args) {
Scala_java.test(); //因为Scala中的类名就是一个对象,导入包以后直接使用就可以 }}
3.4 字符串
在 Scala 中,字符串的类型实际上就是 Java中的 String类,它本身是没有 String 类的。
在 Scala 中,String 是一个不可变的字符串对象,所以该对象不可被修改。这就意味着你如果修改字符串就会产生一个新的字符串对象
object Scala_String {
def main(args:Array[String]):Unit={
val str = "lianzhipeng" val str1 = str.substring(0,2) //取第一个和第二个字母 println(str) // lianzhipeng println(str1) // li }}
3.4.1 字符串连接
object Scala_