1. 用构造器确保初始化
- 构造器采用与类名相同的名称,调用构造器是编译器的责任。
- 构造器有无参构造器(默认构造器)以及有参构造器,构造器无返回值。
- 当没有定义类的构造器时,创建对象直接调用默认构造方器。
- 当定义了有参构造器时,如需调用无参构造器,则需申明无参构造器。
- 在多线程情况下,只能有一个线程调用某一个对象的构造方法,因此构造方法是同步的。
2. 方法重载
- 区分方法重载是,每个重载方法参数列表是不一样的,甚至参数顺序不一样也足以区分两个方法,但一般情况不这么做。而与返回值无关。
- 基本类型可以从一个较小的类型自动提升至一个较大的类型。
- 如果传入一个较大的类型将需要显示的类型强制转换,不然编译器会报错。
4. this关键字
- this关键字就是当前对象的引用。
- 在构造器中调用构造器:
- 调用构造器的这条语句必须在第一句。
- 尽管可以用this调用一个构造器,但是不能调用两个。
- 除构造器之外,编译器禁止在任何其他方法中调用构造器。
package initialization;
import static net.mindview.util.Print.*;
public class Flower {
int petalCount = 0;
String s = "initial value";
Flower(int petals) {
petalCount = petals;
print("Constructor w/ int arg only, petalCount= " + petalCount);
}
Flower(String ss) {
print("Constructor w/ String arg only, s = " + ss);
s = ss;
}
Flower(String s, int petals) {
this(petals);
// ! this(s); // Can't call two!
this.s = s; // Another use of "this"
print("String & int args");
}
Flower() {
this("hi", 47);
print("default constructor (no args)");
}
void printPetalCount() {
// ! this(11); // Not inside non-constructor!
print("petalCount = " + petalCount + " s = " + s);
}
public static void main(String[] args) {
Flower x = new Flower();
x.printPetalCount();
}
} /* * Output: Constructor w/ int arg only, petalCount= 47 String & int args default * constructor (no args) petalCount = 47 s = hi */// :~
1. static的含义
- 了解完this关键字之后,就能更全面的理解static(静态)方法的含义。static方法就是没有this指针的方法。
- 在static方法的内部不能调用非静态方法,反过来可以。
- 可以在没有创建任何对象的前提下,通过类名.方式调用方法。
- static可以修饰变量、常量、方法、类名,一经修饰,则说明该内容为类所共有,所有类的对象共享。
5. 清理:终结处理和垃圾回收
1. finalize的用途以及介绍
- 垃圾回收器只知道回收由new分配的内存。一旦垃圾回器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
- 所以要是打算使用finalize(),就能在垃圾回收时刻做一些重要的清理工作。
- 或者可以在finalize()方法里进行自救(重新与引用链上的任何一个对象建立连接即可),譬如把自己this引用赋值给某个类变量或对象的成员变量。
- 但是,这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次。
2. finalize、final、finally的区别
-
性质不同
- finalize()为方法;
- final为关键字;
- finally为区块标志,用于try语句中;
-
作用
- finalize():Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象进行垃圾回收。用户自定义时,用于释放对象占用的资源(比如进行I/0操作)。
- final:修饰的变量,方法,类,代表变量值不可改,方法不可被重写,类不能被继承。final标识的关键字存储在常量池中。
- finally:finally{}用于标识代码块,与try{}进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行。
6. 成员初始化
- Java尽力保证所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。
- 类的数据成员是基本类型都会保证有一个初始值,如int为0,boolean为false等。
- 如果是一个对象引用时,默认初始化为null。
- 指定初始化:
public class InitialValues2 {
boolean bool = true;
char ch = 'x';
byte b = 47;
short s = 0xff;
int i = 999;
long lng = 1;
float f = 3.14f;
double d = 3.14159;
}
7. 构造器初始化
可以用构造器来进行初始化。在运行时刻,可以调用方法或执行某些工作来确定初值,为编程带来了更大的灵活性。但注意:无法阻止自动初始化的进行,它将在构造器被调用之前发生。因此,如下代码:
public class Counter {
int i;
Counter() { i = 7; }
// ...
}
那么i首先会被置为0,然后变成7。对于所有基本类型和对象的引用,包括在定义时已经指定初值的变量,这种情况是成立的,而final常量则不是,而是直接指定。
1. 初始化顺序
- 在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,他们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
2. 静态数据的初始化
- 无论创建多少个对象,静态数据只占一份存储区域。
package initialization;//: initialization/StaticInitialization.java
// Specifying initial values in a class definition.
import static net.mindview.util.Print.*;
class Bowl {
Bowl(int marker) {
print("Bowl(" + marker + ")");
}
void f1(int marker) {
print("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
print("Table()");
bowl2.f1(1);
}
void f2(int marker) {
print("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
print("Cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
print("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
print("Creating new Cupboard() in main");
new Cupboard();
print("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
运行结果:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
对象创建过程:
类变量/静态代码块->main()->实例变量/构造块->构造方法
- 即使没有显示的使用static关键字,构造器实际上是静态方法。因此首次创建类型为Dog的对象时,或者Dog类的静态方法/静态域首次被访问时,java解释器必须查找类路径,以定位Dog.class文件。
- 然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化旨在Class对象首次加载的时候进行一次。
- 当用new Dog()创建对象时,首先在堆上为Dog对象分配足够的存储空间。
- 这块存储空间会被清零,这就自动地将Dog对象中所有的基本类型数据都设置了默认值,而引用也被设置成了null。
- 执行所有出现于字段定义出的初始化动作。
- 执行构造器。