《疯狂Java讲义》

1、Java语言既具有解释型语言的特征,也具有编译型语言的特征,因为Java程序要经过先编译,后解释两个步骤。

2、编译型语言是指使用专门的编译器,针对特定平台(操作系统)将源代码一次性“翻译”成可被该平台硬件执行的机器码,并包装成该平台所能识别的可执行性程序的格式,这个转换过程称为编译。编译生成的可执行性程序可以脱离开发环境,在特定平台上独立运行。但因为编译型语言的程序被编译成特定平台的机器码,因此编译生成的可执行性程序通常无法移植到其他平台上运行。

3、解释型语言是指使用专门的解释器对源程序逐行解释成特定平台的机器码,并立即执行的语言。解释型语言通常不会进行整体性的编译和链接处理,解释型语言相当于把编译型语言中的编译和解释过程混合到一起同时完成。可以认为:每次执行解释型语言的程序都需要进行一次编译,因此解释型语言的程序运行效率通常较低,而且不能脱离解释器独立运行。但解释型语言有一个优势:跨平台比较容易,只需提供特定平台的解释器即可。解释型语言可以方便地实现源程序级的移植,但这是以牺牲程序执行效率为代价的。

4、Java语言是一门强类型语言。强类型包含两方面的含义:①所有的变量必须先声明后使用;②指定类型的变量只能接受类型与之匹配的值。强类型语言可以在编译过程中发现源代码的错误,从而保证程序更加健壮。

5、一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变。

6、this关键字总是指向调用该方法的对象:

       1)在构造器中引用该构造器正在初始化的对象

       2)在方法中引用调用该方法的对象

this可以代表任何对象,当this出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的,它所代表的对象只能是当前类;只有当这个方法被调用时,它所代表的对象才能被确定下来:谁在调用这个方法,this就代表谁。可以省略this前缀。

7、方法不能独立存在,方法必须属于类或对象。同一个类的一个方法调用另外一个方法时,如果被调方法是普通方法,则默认使用this作为调用者;如果被调方法是静态方法,则默认使用类作为调用者。也就是说,表面上看起来某些方法可以被独立执行,但实际上还是使用this或者类来作为调用者。

7、局部变量定义后,必须经过显示初始化后才能使用,系统不会为局部变量执行初始化。这意味着定义局部变量后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋初始值时,系统才会为局部变量分配内存,并将初始值保存到这块内存中。局部变量不属于任何类或者实例,因此它总是保存在其所在方法的栈内存中。

8、子类不能获得父类的构造器,但子类构造器里可以调用父类构造器的初始化代码。

9、BaseClass和SubClass中都定义了名为a的实例变量,则SubClass的a实例变量将会隐藏BaseClass的a实例变量。当系统创建了SubClass对象时,实际上会为SubClass对象分配两块内存,一块用于存储在SubClass类中定义的a实例变量,一块用于存储从BaseClass类继承得到的a实例变量。系统查找a的顺序为:

       1)查找该方法中是否有名为a的局部变量。

       2)查找当前类中是否包含名为a的成员变量。

       3)查找a的直接父类中是否包含名为a的成员变量,依次上溯a的所有父类,直到

java.lang.Object类,如果最终不能找到名为a的成员变量,则系统出现编译错误。

10、在构造器中,因为this调用和super调用都要放在第一行,所有this调用和super调用不会同时出现。不管是否使用super调用来执行父类构造器的初始化代码,子类构造器总会调用父类构造器一次。子类构造器调用父类构造器分如下几种情况:

       1)子类构造器执行体的第一行使用super显式调用父类构造器,系统将根据super调

用里传入的实参列表调用父类对应的构造器。

       2)子类构造器执行体的第一行代码使用this显式调用本类中重载的构造器,系统将根

据this调用类传入的实参列表调用本类中的另一个构造器。执行本类中另一个构

造器时即会调用父类构造器。

       3)子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构

造器之前,隐式调用父类无参数的构造器。

不管上面哪种情况,当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行;不仅如此,执行父类构造器时,系统会再次上溯执行其父类构造器。。。。依次类推,创建任何Java对象,最先执行的总是java.lang.Object类的构造器。

11、Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。编译时类型是BaseClass,而运行时类型是SubClass,当调用该引用变量的test( )方法(BaseClass类中定义了该方法,子类SubClass覆盖了父类的该方法)时,实际执行的是SubClass类中覆盖后的test( )方法,这就是多态。但与方法不同的是,对象的实例变量则不具有多态性,通过引用变量来访问其包含的实例变量时,系统总是试图访问它编译时类型所定义的成员变量,而不是它运行时类型所定义的成员变量。引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法。因此,编写Java代码时,引用变量只能调用声明变量时所用类里包含的方法。例如,通过Object p = new Person( )代码定义一个变量p,则这个p只能调用Object类的方法,而不能调用Person类里定义的方法。

12、初始化块虽然也是Java类的一张成员,但它没有名字,也就没有标识,因此无法通过类、对象来调用初始化块。初始化块只在创建Java对象时隐式执行,而且在执行构造器之前执行。实际上初始化块是一个假象,使用javac命令编译Java类后,该Java类中的初始化块会消失——初始化块中的代码会被“还原”到每个构造器中,且位于构造器所有代码的前面。

13、当JVM第一次主动使用某个类时,系统会在类准备阶段为该类的所有静态成员变量分配内存;在初始化阶段则负责初始化这些静态成员变量,初始化静态成员变量就是执行类初始化代码或者声明类成员变量时指定的初始值,它们的执行顺序与源代码中的排列顺序相同。

14、常量池专门用于管理在编译时被确定并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。常量池保证相同的字符串直接量只有一个,不会产生多个副本。

15、final修饰变量时,表示该变量一旦获得了初始值就不可被改变。final修饰的成员变量必须由程序员显式地指定初始值,系统不会对final成员进行隐式初始化:

       1)类变量:必须在静态初始化块中指定初始值或声明该类变量时指定初始值,而且只能在两个地方的其中之一指定。

       2)实例变量:必须在非静态初始化块、声明该实例变量时或者构造器中指定初始值,而且只能在三个地方的其中之一指定。

16、如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值;如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能再对该变量赋值。如果final修饰形参,因为形参在调用该方法时,由系统根据传入的参数来完成初始化,因此使用final修饰的形参不能被赋值。当定义final变量时就为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那么这个final变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方直接替换成该变量的值。对于final实例变量来说,只有在定义该变量时指定初始值才会有“宏变量”的效果。

17、实现接口方法时,必须使用public访问控制修饰符,因为接口里的方法都是public的,而子类(相当于实现类)重写父类方法时访问权限只能更大或者相等,所以实现类实现接口里的方法只能使用public访问权限。

18、通过Arrays工具类里提供的asList( )方法得到的List集合,它不是ArrayList实现类的实例,它只是Arrays的内部类ArrayList的实例。Arrays.ArrayList是一个固定长度的List集合,程序只能遍历该集合中的元素,不可增加、删除该集合中的元素。

19、输入流、输出流都是从程序运行所在内存的角度来划分。输入流主要由InputStream和Reader作为基类,而输出流则主要由OutputStream和Writer作为基类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值