成員變量: 定義在類裏面,爲類全部;能夠被public、private、protect、static修飾;存儲在堆中;沒有被static修飾必須先new對象才能使用;當前類的全部方法均可以調用;若是該類有子類,則子類也能夠調用;能夠不賦值,若是沒有賦值基本數據類型返回對應的值,非基本數據類型返回null。java
定義:ide
public class Test{ public int num; }
初始化方式:函數
一、若是隻是單純的定義一個成員變量而沒有賦值,則編譯器會自動添加相應的默認值。如:spa
public class Test{ //基本數據類型 private boolean flag; //默認值:false private int _int; //默認值:0 private byte _byte; //默認值:0 private char _char; //默認值:'\u0000',可是Eclipse中打印的時候會是空白符"方框",由於空白符的code是0x20,0x20如下爲不可見的控制字符。 private short _short; //默認值:0 private float _float; //默認值:0.0 private long _long; //默認值:0 private double _double; //默認值:0.0 //引用類型默認爲null private String string; }
二、直接賦值 code
public class Test { private int num = 1; private String name = "xiaomin"; public Person person = new Person(); }
三、經過方法初始化對象
public class Test{ private int i = f(); private int j = g(i); private int f() { return 10; } private int g(int i){ return i*2 } }
可是,編譯器在初始化對象的時候是按順序執行的,因此不能像下面那樣的方法來初始化:ip
public class Test{ private int j = g(i); private int i = f(); private int f() { return 10; } private int g(int i){ return i*2 } }
四、經過構造函數初始化編譯器
public class Test{ int num ; public Test(){ num = 10; } }
在進入構造器以前,編譯器會先給num默認初始化爲0,進入構造器以後再賦值爲10。string
初始化順序:it
一個類在編譯的時候是成員變量優先初始化,而成員變量的初始化順序是由成員變量在該類裏面定義的順序決定的。
package com.extendstest; public class OrderOfInitialization { public static void main(String[] args) { Card card = new Card(); card.f(); } } class Tag { Tag(int num) { System.out.println("Tag" + num); } } class Card { Tag tag1 = new Tag(1); //定義tag1變量 Card() { System.out.println("Card()"); tag3 = new Tag(33); //tag3從新初始化了 } Tag tag2 = new Tag(2); //定義tag2變量 void f() { System.out.println("f()"); } Tag tag3 = new Tag(3); //定義tag3變量 }
在main方法裏面建立了一個card對象的,編譯器在編譯Card類時,成員變量tag一、tag二、tag3的初始化工做是在構造器Card()以前,所以,上述代碼輸出結果爲:
Tag1 Tag2 Tag3 Card() Tag33 f()
static變量的初始化順序:static成員變量優先於非static成員變量。
public class StaticInitialization { public static void main(String[] args) { System.out.println("Creating new Cupboard() in main"); new Cupboard(); System.out.println("Creating new Cupboard() in main"); new Cupboard(); t2.f2(1); t3.f3(1); } static Table t2 = new Table(); static Cupboard t3 = new Cupboard(); } class Bowl{ Bowl(int i){ System.out.println("Bowl"+i); } void f(int i){ System.out.println("f"+i); } } class Table{ static Bowl b1 = new Bowl(1); Table(){ System.out.println("Table()"); b2.f(1); } void f2(int i){ System.out.println("f2("+i+")"); } static Bowl b2 = new Bowl(2); } class Cupboard{ Bowl b3 = new Bowl(3); static Bowl b4 = new Bowl(4); Cupboard(){ System.out.println("Cupboard()"); b4.f(2); } void f3(int i){ System.out.println("f3("+i+")"); } static Bowl b5 = new Bowl(5); }
由於static僅在Class對象首次建立的時候初始化僅發生一次,因此,上面代碼執行結果爲:
Bowl1 Bowl2 Table() f1 Bowl4 Bowl5 Bowl3 Cupboard() f2 Creating new Cupboard() in main Bowl3 Cupboard() f2 Creating new Cupboard() in main Bowl3 Cupboard() f2 f2(1) f3(1)
還有如下靜態塊裏初始化方式也是:
class Cup{ Cup(int i){ System.out.println("Cup("+i+")"); } void f(int i){ System.out.println("f("+i+")"); } } class Cups{ static Cup c1; static Cup c2; static { //靜態塊初始化 c1 = new Cup(1); c2 = new Cup(2); } Cups(){ System.out.println("Cups()"); } } public class StaticInitialization { public static void main(String[] args) { System.out.println("Inside main()"); Cups.c1.f(99); } static Cups x = new Cups(); static Cups y = new Cups(); }
執行結果:
Cup(1) Cup(2) Cups() Cups() Inside main() f(99)
另一種,非靜態實例初始化,沒有static關鍵字,:
package com.extendstest; class Mug{ Mug(int i){ System.out.println("Mug("+i+")"); } void f(int i ){ System.out.println("f("+i+")"); } } public class Mugs { Mug c1; Mug c2; { //非靜態初始化,建立對象時會屢次調用 c1 = new Mug(1); c2 = new Mug(2); System.out.println("c1&&c2inin...."); } Mugs(){ System.out.println("Mugs()"); } public static void main(String[] args) { System.out.println("inin..main"); Mugs x = new Mugs(); Mugs y = new Mugs(); } }
執行結果:
inin..main Mug(1) Mug(2) c1&&c2inin.... Mugs() Mug(1) Mug(2) c1&&c2inin.... Mugs()