1. Java类的初始化顺序:
(1).在一个类中,初始化顺序由变量在类中的声明定义顺序决定,成员变量(非set方法和构造方法的初始化)的初始化发生在方法调用之前,包括构造方法。
(2).静态变量在整个存储区只保留一份拷贝,本地变量不能使用静态关键字,基本类型的静态变量不需要初始化,它会根据类型获得初始化值,引用类型的静态变量默认初始化为null。
静态变量的初始化发生在需要使用的时候,一旦被初始化之后,静态变量就不会再初始化。
(3).静态初始化块和静态变量类似的执行也在构造方法之前,并且仅执行一次。
(4).动态初始化块(与静态初始化块类似,只是没有static关键字,即放在一对大括号中的代码块)在静态初始化块初始化结束后执行,动态初始化块每次创建新对象都会初始化一次。
(5).构造方法执行时,先执行父类的构造方法,后执行子类的构造方法。
(6).本地变量初始化最晚,在方法中初始化。
综述,类的初始化顺序依次为:
a.父类的静态变量/静态初始化块;
b.子类类的静态变量/静态初始化块;
c.父类的动态初始化块、非构造方法和set方法的成员变量初始化
d.子类的动态初始化块、非构造方法和set方法的成员变量初始化
e.父类的构造方法。
f.子类的构造方法。
g.父类本地变量。
h.子类的本地变量。
在这里有必要总结一下对象的创建过程。请考虑一个名为 Dog 的类:
(1) 类型为 Dog 的一个对象首次创建时,或者 Dog 类的 static 方法/ static 字段首次访问时, Java 解释器
必须找到 Dog.class(在事先设好的类路径里搜索)。
(2) 找到 Dog.class 后(它会创建一个 Class 对象,这将在后面学到),它的所有 static 初始化模块都会运
行。因此, static 初始化仅发生一次—— 在 Class 对象首次载入的时候。
(3) 创建一个 new Dog()时, Dog 对象的构建进程首先会在内存堆( Heap)里为一个 Dog 对象分配足够多的存
储空间。
(4) 这种存储空间会清为零,将 Dog 中的所有基本类型设为它们的默认值(零用于数字,以及 boolean 和
char 的等价设定)。
(5) 进行字段定义时发生的所有初始化都会执行。
(6) 执行构建器。正如第 6 章将要讲到的那样,这实际可能要求进行相当多的操作,特别是在涉及继承的时
候。
static方法→ 初始化数值或方法→执行构造器
1.1 this关键字
调用当前对象,也可调用当前对象的构造器.
1.2 默认构造器
默认构造器没有形式参数,作用是创建一个默认对象。若类中没有构造器,则编译器会自动创建一个默认构造器。
没有提供构造器->编译器认为需要一个构造器,我给你制造一个。
已经有了构造器->编译器认为已写了构造器,你知道你在做什么,你是刻意省略默认构造器的。
2. java中的析构函数:
Java中没有像C/C++的析构函数,用来销毁不用的对象是否内存空间,只有以下三个方法用于通知垃圾回收器回收对象。
(1).finalize( )只是通知JVM的垃圾收集器当前的对象不再使用可以被回收了,但是垃圾回收器根据内存使用状况来决定是否回收。
finalize()最有用的地方是在JNI调用本地方法时(C/C++方法),调用本地方法的析构函数消耗对象释放函数。
(2). System.gc()是强制析构,显式通知垃圾回收器释放内存,但是垃圾回收器也不一定会立即执行,垃圾回收器根据当前内存使用状况和对象的生命周期自行决定是否回收。
(3).RunTime.getRunTime().gc()和System.gc()类似。
注意:这三个函数都不能保证垃圾回收器立即执行,推荐不要频繁使用。
3.方法重载(Method Overloading)
定义:方法名不同而形式参数不同,适用于构造器和其它方法。
区分重载方法:每个重载的方法都必须有一个独一无二的参数类型列表。
涉及基本类型的重载:基本类型从一个较小的类型自动提升到一个较大的类型。
以返回值区分重载方法:行不通,如下所示:
void f(){}
int f(){
return 1;
}
f();
Java无法判断该调用哪个f()方法。
4 . static的含义
static(静态)方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来可以。static方法一般最先初始化,初始化过一次不会再初始化第二次.
static方法的主要用途:可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。(很像全局方法,但是在Java中禁止使用全局方法,但在类中置入static方法就可以访问其他static方法和static域)
由于不存在this,所以静态方法不是通过"向对象发送消息"的方式来完成的。
5 . 数组
Java中数组初始化有以下3种方式:
(1).数组声明时直接初始化,如:
int[] a = {1,2,3};
(2).动态数组初始化,如:
int[] a = new int[]{1,2,3};
注意:动态数组初始化时,不能在new()操作符中指定数组的大小,即int[] a = new int[3]{1,2,3}的写法是错误的,数组的大小由初始化数组元素个数决定。
(3).固定长度数组初始化,如:
int[] a = new int[3];
a[1] = 0;
a[2] = 1;
a[3] = 2;
//多维数组
public class MultiDimWrapperArray {
public static void main(String[] args) {
Integer[][] a1 = { // Autoboxing
{ 1, 2, 3, }, { 4, 5, 6, }, };
Double[][][] a2 = { // Autoboxing
{ { 1.1, 2.2 }, { 3.3, 4.4 } }, { { 5.5, 6.6 }, { 7.7, 8.8 } },
{ { 9.9, 1.2 }, { 2.3, 3.4 } }, };
String[][] a3 = { { "The", "Quick", "Sly", "Fox" },
{ "Jumped", "Over" },
{ "The", "Lazy", "Brown", "Dog", "and", "friend" }, };
System.out.println("a1: " + Arrays.deepToString(a1));
System.out.println("a2: " + Arrays.deepToString(a2));
System.out.println("a3: " + Arrays.deepToString(a3));
}
}// Result:
// a1: [[1, 2, 3], [4, 5, 6]]
// a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]], [[9.9, 1.2], [2.3,
// 3.4]]]
// a3: [[The, Quick, Sly, Fox], [Jumped, Over], [The, Lazy, Brown, Dog, and,
// friend]]