Java 靜態變量、常量和方法筆記

1. 爲何要使用靜態變量、常量和方法java

     一般,在處理問題,會遇到多個不一樣的類要使用同一變量,常量或方法,然而,同一個常量在不一樣的類中建立時系統都會爲之分配內存,形成內存浪費,若是能將這些不一樣類中的變量共享到一個內存中,那就大大減小了內存的使用,而靜態變量(關鍵字 static)就是解決這個問題的。以下圖所示:函數

 

 

 

 

 

 

 

 

2. 被聲明的static的變量,常量和方法被稱爲靜態成員,靜態成員屬於類全部,區別於個別對象,能夠在本類或其餘類使用類名「.」運算符調用靜態成員。以下代碼:ui

1 public class AnyThing {
 2     static double PI = 3.1415;           //在類中定義靜態常量
 3     static int id;                       //在類中定義靜態變量
 4     public static void method1(){        //在類中定義靜態方法
 5         
 6     }
 7     public void method2(){
 8         System.out.println(AnyThing.PI);  //調用靜態常量
 9         System.out.println(AnyThing.id);  //調用靜態變量
10         AnyThing.method1();               //調用靜態方法
11     }
12 }

注意:(1) 雖然靜態成員可使用「對象.靜態成員」的形式進行調用,但一般不這麼使用,這樣容易混淆靜態成員和非靜態成員。this

             (2) 在靜態方法中不可使用this關鍵字。code

             (3) 在靜態方法中不能夠直接調用非靜態方法。orm

             (4) 在Java中規定不能將方法中的局部變量聲明爲static的。對象

             (5) 若是在執行類時,但願先執行類的初始化動做,可使用static定義一個靜態區域,例如blog

1 public class example{
2    static{
3          ...
4    }
5 }

當這段代碼被執行時,首先執行static塊中的程序,而且只會執行一次,即在類加載的時候就被執行,以後執行main()方法。而且只是自上而下的順序執行。繼承

3.在java中,靜態方法和普通方法的區別:內存

一、在外部調用靜態方法時,可使用"類名.方法名"的方式,也可使用"對象名.方法名"的方式。而實例方法只有後面這種方式。也就是說,調用靜態方法能夠無需建立對象。
 
二、靜態方法在訪問本類的成員時,只容許訪問靜態成員(即靜態成員變量和靜態方法),而不容許訪問實例成員變量和實例方法;實例方法則無此限制。

三、程序的static塊只能調用靜態方法,不能調用實例的方法。

若是要追溯其區別的根源,能夠這樣理解:在編譯期間靜態方法的行爲就已經肯定,而實例方法只有在運行期間當實例肯定以後才能肯定。

基本練習

package test_01;

public class static_class {
    
    static int a =100;
    int b=200;                      //實例變量

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        // static int a =100;       //局部變量不能定義static
        System.out.println("主函數");
        static_fangfa();
        //public_fangfa();   //也不能在靜態函數中調用靜態函數 ,除非把非靜態函數變爲靜態函數
    }
    
    // 靜態塊
    static {
        System.out.println("靜態塊");
    }
    

    public static_class() {
        // TODO Auto-generated constructor stub
        System.out.println("構造方法");    
    }
    
    private static void static_fangfa() {

        System.out.println("靜態函數"); 
        static_class static_class1 =new static_class();
        System.out.println(static_class1.a);
        // System.out.println(static_class.b);   // 靜態函數裏面不能調用靜態變量
    }
    
    public void public_fangfa() {
        int c = 100+b;
        System.out.println("非靜態函數"+c);
    }
}

輸出結果:

靜態塊
主函數
靜態函數
構造方法
100

4.靜態代碼段

a. 靜態代碼塊只能定義在類裏面,它獨立於任何方法,不能定義在方法裏面

b.靜態代碼塊裏面的變量都是局部變量,只在本塊內有效

c.靜態代碼塊會在類被加載時自動執行,而不管加載者是JVM仍是其餘的類

d. 一個類中容許定義多個靜態代碼塊,執行的順序根據定義的順序進行

e.靜態代碼塊只能訪問類的靜態成員,而不容許訪問實例成員

5.java中的初始化順序

JAVA類首次裝入時,會對靜態成員變量或方法進行一次初始化,但方法不被調用是不會執行的,靜態成員變量和靜態初始化塊級別相同,非靜態成員變量和非靜態初始化塊級別相同。

初始化順序:先初始化父類的靜態代碼--->初始化子類的靜態代碼-->
(建立實例時,若是不建立實例,則後面的不執行)初始化父類的非靜態代碼(變量定義等)--->初始化父類構造函數--->初始化子類非靜態代碼(變量定義等)--->初始化子類構造函數

類只有在使用New調用建立的時候纔會被JAVA類裝載器裝入建立類實例時,首先按照父子繼承關係進行初始化類實例建立時候,首先初始化塊部分先執行,而後是構造方法;而後從本類繼承的子類的初始化塊執行,最後是子類的構造方法類消除時候,首先消除子類部分,再消除父類部分

  • 靜態變量: 在類內部中,方法的外部聲明的對象並且加上static;
  • 實例變量: 在類內部中,聲明不須要加static;
  • static 函數名() --> 能夠經過 類名.函數名() 調用,也能夠經過 類對象.函數名() 調用;

  • 函數名()   -->只能經過類對象.函數名()  調用;

6.Java靜態對象和非靜態對象的區別

                                        靜態對象                                                       非靜態對象     
擁有屬性:               是類共同擁有的                                            是類各對象獨立擁有的
內存分配:              內存空間上是固定的                                      空間在各個附屬類裏面分配 
分配順序:              先分配靜態對象的空間                    繼而再對非靜態對象分配空間,也就是初始化順序是先靜態再非靜態。

7.Java靜態對象的特色

A,靜態對象的數據在全局是惟一的,一改都改。若是你想要處理的東西是整個程序中惟一的,弄成靜態是個好方法。非靜態的東西你修改之後只是修改了他本身的數據,可是不會影響其餘同類對象的數據。 
B,引用方便。直接用類名.靜態方法名  或者  類名.靜態變量名就可引用而且直接能夠修改其屬性值,不用get和set方法。
C,保持數據的惟一性。此數據全局都是惟一的,修改他的任何一處地方,在程序全部使用到的地方都將會體現到這些數據的修改。有效減小多餘的浪費。

D,static final用來修飾成員變量和成員方法,可簡單理解爲「全局常量」。對於變量,表示一旦給值就不可修改;對於方法,表示不可覆蓋。

8.靜態變量、靜態方法和靜態塊

       一般狀況下,類成員必須經過它的類的對象訪問,可是能夠建立這樣一個成員,它可以被它本身使用,而沒必要引用特定的實例。在成員的聲明前面加上關鍵字static就能建立這樣的成員。若是一個成員被聲明爲static,它就可以在它的類的任何對象建立以前被訪問,而沒必要引用任何對象(跟類是否有static修飾無關)。

       你能夠將方法和變量都聲明爲static。static 成員的最多見的 例子是main( ) 。聲明爲static的方法有如下幾條限制: ·

A,它們僅能調用其餘的static 方法

B,它們只能訪問static數據

C,它們不能以任何方式引用this 或super(this涉及到對象,super 與繼承有關)

       示例:Static 塊僅在該類被加載時執行一次。下面的例子顯示的類有一個static方法,一些static變量,以及一個static 初始化塊。

public class TestNew {  
    static int a = 3;  
    static int b;  
    static void meth(int x){  
        System.out.println("x = "+x);  
        System.out.println("a = "+a);  
        System.out.println("b = "+b);  
    }  
    static {  
        System.out.println("static block initialized");  
        b = a*4;  
    }  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        meth(42);  
    }  
}

執行結果是:

static blockinitialized
x = 42
a = 3
b = 12

      上述classTestNew的執行順序是:首先static 塊執行(打印一條消息),a被設置爲3,最後b被初始化爲a*4 成12。而後調用main(),main () 調用meth() ,把值42傳遞給x。3個println ( ) 語句引用兩個static變量a和b,以及局部變量x 。

9.外部使用靜態變量或者靜態方法

       在定義它們的類的外面,static方法和變量能獨立於任何對象而被使用,你只要在類的名字後面加點號運算符便可。能夠看到,這種格式與經過對象引用變量調用非static方法或者變量的格式相似。示例:

class StaticDemo{  
    static int a = 42;  
    static int b = 99;  
    static void callme(){  
        System.out.println("a = "+a);  
    }  
}  
public class TestNew {  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        StaticDemo.callme();  
        System.out.println("b = "+StaticDemo.b);  
    }  
}

  執行結果:

a = 42
b = 99

10.靜態內部類

靜態內部類是指在一個類的內部,又定義了一個用static修飾的類。

A,首先,用內部類是由於內部類與所在外部類有必定的關係,每每只有該外部類調用此內部類。因此沒有必要專門用一個Java文件存放這個類。

B,靜態方法、靜態成員變量。它惟一的做用就是隨着類的加載(而不是隨着對象的產生)而產生,以至能夠用類名+靜態成員名直接得到。這樣靜態內部類就能夠理解了,它能夠直接被用外部類名+內部類名得到。

public class Build {
      ..............
    public static class VERSION {
           ................
           public static final String RELEASE =getString("ro.build.version.release");
           ................
     }
     ................
}

在外部能夠直接經過Build.VERSION.RELEASE來訪問。

11. 靜態常量

靜態常量不可變,能夠直接被訪問,如類名.靜態常量名。例如:

public class MathTest{
   public static final double PI= 3.1415926;
}

能夠直接採用MathTest.PI的形式訪問該PI常量。

13. 靜態類與內部類的區別

內部類

一、內部類擁有普通類的全部特性,也擁有類成員變量的特性 
二、內部類能夠訪問其外部類的成員變量,屬性,方法,其它內部類

靜態內部類

一、只有內部類才能聲明爲static,也能夠說是靜態內部類 
二、只有靜態內部類才能擁有靜態成員,普通內部類只能定義普通成員 
三、靜態類跟靜態方法同樣,只能訪問其外部類的靜態成員 
四、若是在外部類的靜態方法中訪問內部類,這時候只能訪問靜態內部類

/**
 * 外部類,不能聲明爲 static
 * 
 * @author zhanqi
 * 
 */
public class OuterClass {
    private int ab = 1;
    private static int sab = 2;
    /**
     * 普通內部類
     */
    public class NormalInnerClass {
        // private static int age = 22;
        private int age = 22; // 不能聲明爲static
        public NormalInnerClass() {
            // 能夠訪問外部類靜態與非靜態成員
            System.out.println(ab);
            System.out.println(sab);
        }
    }
    /**
     * 靜態內部類
     */
    public static class StaticInnerClass {
        // 定義靜態與非靜態成員都是能夠的
        private static int age = 22;
        private int age2 = 22;
        private void echo() {
            // System.out.println(ab);
            System.out.println(sab);// 只能訪問外部類的靜態成員
        }
    }
}

內部類實例化

1.訪問內部類,必須使用:外部類.內部類,OutClass.InnerClass 
2.普通內部類必須綁定在其外部類的實例上 
3.靜態內部類能夠直接 new

/**
 * 外部類訪問內部類
 */
public class OuterClass {/**
     * 普通方法
     */
    public void method() {
        StaticInnerClass sic = new StaticInnerClass();
        NormalInnerClass nic = new NormalInnerClass();
    }/**
     * Main
     */
    public static void main(String[] args) {
        // 在靜態方法中,只能訪問靜態成員,靜態內部類
        // NormalInnerClass nic = new NormalInnerClass();
        StaticInnerClass sic = new StaticInnerClass();
    }
}/**
 * 其它類訪問內部類
 */
class Test {
    public static void main(String[] args) {
        /**
         * 1:其它類訪問內部類,必須使用:外部類.內部類,OutClass.InnerClass
         * 2:普通內部類必須綁定在其外部類的實例上
         * 3:靜態內部類能夠直接 new
         */
        OuterClass.StaticInnerClass sic = new OuterClass.StaticInnerClass();
        // OuterClass.NormalInnerClass n = new OuterClass.NormalInnerClass();OuterClass oc = new OuterClass();
        OuterClass.NormalInnerClass nic = oc.new NormalInnerClass();
    }
}

靜態對象

靜態對象咱們常用,可是對靜態對象和非靜態對象的區別卻並不必定那麼瞭解。下表格就是靜態對象和非靜態對象主要區別。

1.擁有的對象,靜態對象是類共同擁有的 ,而非靜態對象是由類單獨擁有;  2.內存空間,靜態對象內存空間是固定,非靜態類對象是附着相關類的分配;  3.分配順序,先分配靜態對象的空間,而後纔會分配非靜態對象也就是初始化。

相關文章
相關標籤/搜索