1. 程式人生 > 其它 >Head First Java學習:第十章-數字很重要

Head First Java學習:第十章-數字很重要

 1、Math 方法:最接近全域性的方法

一種方法的行為不依靠例項變數值,方法對引數執行操作,但是操作不受例項變數狀態影響,那麼為了執行該方法去堆上建立物件例項比較浪費。

舉例:

Math mathObject = new Math();

報錯:Math() has private access in java.lang.Math

而是可以直接使用:

int x = Math.round(43.4);

int y = Math.min(43,23);

int z = Math.abs(-34);

總結:在Math這個類中的所有方法都不需要例項變數值。因為這些方法都是靜態的,所以無需Math的例項,你會用到的只有類本身。

2、非靜態方法與靜態方法的差別

當 需要方法而不需要類的例項,那麼可以用 static 關鍵字標記出該。

使用 static 關鍵字標記“不需要類例項的方法”,稱為“靜態方法”。

舉例:

public static int min(int a,int b){

    //返回a與b中較小的值

}

如何呼叫:

  • 以類的名稱呼叫靜態方法:min(88,43);
  • 以引用變數的名稱呼叫非靜態的方法:

Song t = new Song();

t.play();

3、帶有靜態方法(static)的含義

抽象類(abstract修飾),不能創建出例項,即抽象的類不能被初始化。

非抽象的類如何限制初始化?

把構造方法標記為私有(private,只能被同一類的程式呼叫),則無法創建出類的例項,編譯器會知道不能存取這些私有的建構函式。

不代表有一個或多個靜態方法的類不能被初始化,只要有main的類都有靜態方法。main()一般用來啟動或測試其他類,從main() 中建立類的例項並呼叫新例項上的方法。

在類中可以組合靜態方法和非靜態方法。非靜態方法都需要以某種例項操作,取得新物件的方法只有通過new或者序列化(deserialization)或者Java Reflection Api。

4、靜態方法呼叫其他方法和變數

第一:靜態方法不能呼叫非靜態的變數

靜態方法使用通過類的名稱來呼叫,不需要類的例項(不知道堆上有哪些例項),所以也無法引用到該類的任何例項變數,也不會知道可以使用哪個例項變數值。

如果呼叫非靜態的變數,會報錯:non-static variable size cannot be referenced from a static context

第二:靜態方法不能呼叫非靜態的方法

非靜態方法都是以例項變數的狀態來影響該方法的行為。呼叫非靜態方法,會在非靜態方法中用到例項變數,但是靜態方法無法引用該類的任何例項變數。

如果呼叫非靜態的方法,會報錯:non-static method getSize() cannot be referenced from a static context

 

5、靜態變數

靜態變數是共享的。

同一個類所有的例項共享一份靜態變數。

例項變數:每個例項一個

靜態變數:每個類一個,也叫類變數。類名.靜態變數名 存取

程式碼舉例:

package chap10;

public class Duck {
    private int size;
    // 靜態變數只有在類第一次載入的時候被初始化
    static int duckCount = 0;

    // 建構函式執行時,靜態變數duckCount的值就會增加1
    public Duck(){
        duckCount ++;
        System.out.println("duckCount的值是:"+duckCount);
    }

    public void setSize(int s){
        size = s;
    }

    public int getSize(){
        return size;
    }

}
package chap10;

public class TestDuck {
    public static void main(String[] args) {
        Duck d1 = new Duck();
        d1.setSize(10);
        System.out.println(d1.getSize());
        Duck d2 = new Duck();
        d2.setSize(20);
        System.out.println(d2.getSize());
        Duck d3 = new Duck();
        d3.setSize(30);
        System.out.println(d3.getSize());
        Duck d4 = new Duck();
        d4.setSize(40);
        System.out.println(d4.getSize());
        System.out.println("靜態變數duckCount的值:"+Duck.duckCount);

    }
}

結果:

duckCount的值是:1

10

duckCount的值是:2

20

duckCount的值是:3

30

duckCount的值是:4

40

靜態變數duckCount的值:4

靜態變數的起始動作:類被載入時初始化。

靜態專案的初始化有兩項保證:

  • 靜態變數會在該類的任何物件建立之前就完成初始化
  • 靜態變數會在該類的任何靜態方法執行之前就初始化

預設值:主資料型別:0/0.0/false;物件引用:null

如果沒有給靜態變數賦初值,它會被設定預設值。靜態變數的預設值就是該變數型別的預設值。

6、靜態的final變數是常數

標記為final的變數,一旦被初始化就不會改動;

類載入後,靜態final變數就一直會維持原值。

舉例:public static final double PI = 3.141592653589793;

  • public 可以供各方讀取
  • static,不需要Math的例項
  • final,類載入後,不變

注意:如何區分變數為不變的常數:都是大寫字母!

靜態final變數初始化:

方法一:宣告的時候

public class Foo{
    public static final int FOO_X = 25;
}

方法二:在靜態初始化程式中

public class Foo{

public static final double BAR_SIGN;

// 類載入時執行

static{

    BAR_SIGN = (double) Math.random();

}

}

如果以上兩種方法都沒有使用,編譯器會報錯,變數沒有被初始化

7、其他的final

非靜態final變數:不能改變它的值。

final的方法:不能被覆蓋

final的類:不能被繼承

目的:安全