Java程式設計思想ch5 初始化和清理
阿新 • • 發佈:2019-01-25
5.1 用構造器初始化
new 類名() 將建立和初始化,綁在一起。
5.2 方法過載
5.4 this關鍵字
class Banana{void peel(int i)}{}
public class BananaPeel{
public static void main(String[] args){
Banana a = new Banana(),b = new Banana();
a.peel(1);
b.peel(2);
/*
只有一個peel,編譯器是通過下面方式知道誰呼叫方法。
編譯器將“所操作物件的引用”作為第一個引數傳遞給peel(),
變成Banana.peel(a,1);
Banana.peel(b,2);
所以方法內部有一個物件的引用,用this來指代。
this關鍵字只能在方法內部使用,表示對“呼叫方法的那個物件”的引用。
*/
}
}
在非靜態方法內部可以直接呼叫該類的其他方法,會自動將this傳入。
因為呼叫該非靜態方法的時候已經傳入了物件的引用。
5.4.2 static的含義
static方法就是沒有this傳入的方法。在static方法內部不能直接呼叫非靜態方法,即不能像非靜態方法一樣直接呼叫該類的非靜態方法,因為沒有傳入物件。(但可以通過傳遞一個物件引用,用該引用來呼叫非靜態方法)。
5.7 構造器初始化
無法阻止自動初始化的進行。
public class Counter{
int i;
Counter(){i=7 ;}
}
// i先被初始化為0;再賦值為7;
5.7.1 初始化順序
變數定義即使散落方法定義間,仍舊會在任何方法(包括構造器)被呼叫之前得到初始化。
package Cha5;
import static tools.Print.print;
/**
* Created by YL on 2017/9/7.
*/
class Window {
Window(int marker){print("Window("+marker+")");}
}
class House{
Window w1 = new Window(1);
House(){
print("House()" );
w3 = new Window(33);
}
Window w2 = new Window(2);
void f(){print("f()");}
Window w3 = new Window(3);
}
public class OrderOfInitialization{
public static void main(String[] args){
House h = new House();
h.f();
}
}
靜態資料的初始化
沒有顯示寫出,但構造方法也是靜態的。
呼叫靜態方法和靜態域都要先載入這個類。
非靜態方法和域因為要通過物件來呼叫,在用構造器時,因為構造器是靜態,已經載入了類。
static 關鍵字不能用於區域性變數,只能作用於域。區域性變數是無法成為類的一部分的。
一個靜態域,沒有初始化:基本型別獲得預設值;物件引用為null。
package Cha5;
import static tools.Print.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 bowl = 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();
}
output:
/*程式由主函式開始執行,先初始化main函式所在類的變數,table和cupboard。初始化table要呼叫table建構函式,在此之前,要先初始化Table中靜態變數bowl1和bowl2,列印輸出的前兩行。
初始化順序是先靜態變數,後“非靜態”變數。*/
Bowl(1)
Bowl(2)
// Table的建構函式
Table()
f1(1)
// Cupboard類的靜態變數初始化。
Bowl(4)
Bowl(5)
// 非靜態變數後初始化。
Bowl(3)
//Cupboard構造方法。
Cupboard
f1(2)
// main函式
Creating new Cupboard() in main
// 每建立一個物件,就會建立一份非靜態成員變數。
//所以,會執行Cupboard的第一句 Bowl bowl3 = new Bowl(3);
Bowl(3)
Cupboard
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard
f1(2)
f2(1)
f3(1)
5.7.3 顯示的靜態初始化
靜態塊–這段程式碼只執行一次:當首次生成這個類的一個物件時,或者首次訪問那個類的靜態資料成員時(即便從未生成那個類的物件)。
package Cha5;
import static tools.Print.print;
class Cup{
Cup(int marker){
print("Cup("+marker+")");
}
void f(int marker){
print("f("+marker+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups(){
print("Cups()");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
print("Inside main()");
Cups.cup1.f(99);
}
}
Output:
// main函式列印
Inside main()
// 呼叫Cups的靜態成員變數cup1,會載入這個類。先初始化靜態變數和執行靜態程式碼塊。
// 列印Cup(1);
Cup(1)
Cup(2)
f(99)
5.7.4 非靜態例項初始化
package Cha5;
import static tools.Print.print;
class Mug{
Mug(int marker){
print("Mug("+marker+")");
}
void f(int marker){
print("f("+marker+")");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
// 沒有static,每次新建一個Mugs物件,
// 都會執行一次,因為每個物件都有自己的域。
{
mug1 = new Mug(1);
mug2 = new Mug(2);
print("mug1 & mug2 initialized");
}
Mugs(){
print("Mugs()");
}
Mugs(int i){
print("Mugs(int)");
}
public static void main(String[] args){
print("Inside main()");
new Mugs();
print("new Mugs() completed");
new Mugs(1);
print("new Mugs(1) completed");
}
}
Output:
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
5.8 陣列初始化
int[] a 和 int a[] 都是合理的。
// 只能用於方法定義處
Integer[] a = {new Integer(1), new Integer(2), 3,};
// 可以用於任何地方
Integer[] a = new Integer[] {new Integer(1), new Integer(2), 3,};
5.9 列舉型別
package Cha5;
enum Spiciness{
NOT,MILD,MEDIUM,HOT,FLAMING
}
public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree){
this.degree = degree;
}
public void dedcribe(){
System.out.print("This burrito is");
switch(degree){
case NOT: System.out.println("not spicy at all");
break;
case MILD:
case MEDIUM:
System.out.println("a little hot");
break;
case HOT:
case FLAMING:
default:
System.out.println("maybe too hot");
}
}
public static void main(String[] args) {
Burrito
plain = new Burrito(Spiciness.NOT);
Burrito greenChile = new Burrito(Spiciness.MEDIUM);
Burrito jalapeno = new Burrito(Spiciness.HOT);
plain.dedcribe();
greenChile.dedcribe();
jalapeno.dedcribe();
}
}
This burrito isnot spicy at all
This burrito isa little hot
This burrito ismaybe too hot