国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

深入介紹Java對象初始化

2019-11-26 14:01:38
字體:
供稿:網(wǎng)友

前言

在Java中,一個對象在可以被使用之前必須要被正確地初始化,這一點是Java規(guī)范規(guī)定的。

自動初始化(默認值)

一個類的所有基本數(shù)據(jù)成員都會得到初始化,運行下面的例子可以查看這些默認值:

class Default{  boolean t;  char c;  byte b;  short s;  int i;  long l;  float f;  double d;  public void show() {    System.out.println("基本類型  初始化值/n"+            "boolean<----->" + t +"/n" +            "char<----->" + c +"/n" +            "byte<----->" + b + "/n" +            "short<----->" + s + "/n" +            "int<----->" + i + "/n" +            "long<----->" + l + "/n" +            "float<----->" + f + "/n" +            "double<----->" + d + "/n"    );  }}public class InitValue {  public static void main(String[] args) {    Default d = new Default();    d.show();  }}

【運行結(jié)果】:

基本類型   初始化值

boolean<----->false

char<----->

byte<----->0

short<----->0

int<----->0

long<----->0

float<----->0.0

double<----->0.0

其中,char類型的默認值為空(null)。

對于非基本數(shù)據(jù)類型而言,對象的句柄也會被初始化:

class Person {  private String name;  // setter}class Default {  Person p;  public void show() {    System.out.println("Person<----->" + p);  }}public class InitValue {  public static void main(String[] args) {    Default d = new Default();    d.show();  }}

【運行結(jié)果】:

Person<----->null

可見,句柄初始化值為null。這就是說,如果沒有為p指定初始化值就調(diào)用類似于p.setName的方法,就會出現(xiàn)異常。

規(guī)定初始化

如果需要自己為變量賦一個初始值,可以在定義變量的同時賦值。

class Default{  boolean t = true;  char c = 'A';  byte b = 47;  short s = 0xff;  int i = 24;  long l = 999;  float f = 1.2f;  double d = 1.732;  public void show() {    System.out.println(            "boolean<----->" + t +"/n" +            "char<----->" + c +"/n" +            "byte<----->" + b + "/n" +            "short<----->" + s + "/n" +            "int<----->" + i + "/n" +            "long<----->" + l + "/n" +            "float<----->" + f + "/n" +            "double<----->" + d + "/n"    );  }}public class InitValue {  public static void main(String[] args) {    Default d = new Default();    d.show();  }}

甚至可以通過一個方法來進行初始化;

class Person {  int i = set();  //...}

這些方法也可以使用自變量:

class Person {  int i;  int j = set(i);  //...}

構(gòu)建器初始化

構(gòu)建器進行初始化的優(yōu)點是可以在運行期決定初始化值。例如:

class Person {  int age;  Person() {    age = 89;  }}

age首先會初始化為0,然后變成89。對于所有基本類型以及對象的句柄,這種情況都是成立的。

初始化順序

在一個類里,初始化的順序是由變量在類內(nèi)的定義順序決定的。即使變量定義大量遍布于方法定義的中間,那么變量仍然會在調(diào)用任何方法(包括構(gòu)造函數(shù))之前得到初始化。例如:

class Pet {  Pet(int age) {    System.out.println("Pet(" + age + ")");  }}class Person {  Pet t1 = new Pet(1);  Person() {    System.out.println("---Person()---");    t3 = new Pet(33);  }  Pet t2 = new Pet(2);  void show() {    System.out.println("show----running");  }  Pet t3 = new Pet(3);}public class OrderOfInitialization {  public static void main(String[] args) {    Person p = new Person();    p.show();  }}

【運行結(jié)果】:

Pet(1)

Pet(2)

Pet(3)

---Person()---

Pet(33)<br/>

show----running

上例中,雖然t1、t2、t3的定義遍布于類中,但是初始化的先后順序是由t1、t2、t3的定義順序決定的(自己動手調(diào)換t1、t2、t3看看結(jié)果),且初始化優(yōu)先于構(gòu)建器執(zhí)行,當調(diào)用Person的構(gòu)建器時,t3重新初始化。

靜態(tài)數(shù)據(jù)的初始化

如果數(shù)據(jù)是靜態(tài)的(static),同樣的過程也會執(zhí)行。若屬于基本類型,而且未對其進行初始化,就會自動獲得自己的標準基本類型初始值;若它是指向一個對象的句柄,除非創(chuàng)建一個對象同它連接起來,否則得到一個空值(null)。如果在定義時初始化,采取的方式與非靜態(tài)值是不同的,這是因為static只有一個存儲區(qū)域。例如:

class Bowl {  Bowl(int marker) {    System.out.println("Bowl(" + marker + ")");  }  void f(int marker) {    System.out.println("f(" + marker + ")");  }}class Table {  static Bowl b1 = new Bowl(1);  Table() {    System.out.println("Table()");    b2.f(1);  }  void f2(int marker) {    System.out.println("f2(" + marker + ")");  }  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 marker) {    System.out.println("f3(" + marker + ")");  }  static Bowl b5 = new Bowl(5);}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();}

【運行結(jié)果】:

Bowl(1)

Bowl(2)

Table()

f(1)

Bowl(4)

Bowl(5)

Bowl(3)

Cupboard()

f(2)

Creating new Cupboard() in main

Bowl(3)

Cupboard()

f(2)

Creating new Cupboard() in main

Bowl(3)

Cupboard()

f(2)

f2(1)

f3(1)

靜態(tài)代碼塊

Java允許將其他static初始化工作劃分到類內(nèi)一個特殊的代碼塊中,這種代碼塊的形式為static關(guān)鍵字,后面跟著一個方法主體,稱為靜態(tài)代碼塊。靜態(tài)代碼塊只有在第一次生成那個類的對象或首次訪問屬于那個類的static成員時執(zhí)行。例如:

class Person {  Person(int age) {    System.out.println("Person(" + age + ")");  }  void f(int age) {    System.out.println("f(" + age + ")");  }}class Persons {  static Person p1;  static Person p2;  static {    p1 = new Person(1);    p2 = new Person(2);  }  Persons() {    System.out.println("Persons()");  }}public class ExplicitStatic {  public static void main(String[] args) {    System.out.println("Inside main()");    Persons.p1.f(18);//1  }  static Persons x = new Persons();//2  static Persons y = new Persons();//2}

在標記為1的行內(nèi)訪問static對象p1的時候,或在行1被注釋而行2未被注釋是,用于Persons的static初始化模塊就會運行。若1和2都被注釋掉,則用于Persons的靜態(tài)代碼塊不會執(zhí)行。

靜態(tài)屬性和靜態(tài)代碼塊執(zhí)行的先后順序

class Person {  Person(int age) {    System.out.println("Person("+age+")");  }}class Persons {  static Person p = new Person(2); // 1  static {    p = new Person(3);  }  static Person p = new Person(2); // 2}public class CompStaticInit {  public static void main(String[] args) {  }  static Persons x = new Persons();}

根據(jù)注釋1保留2,注釋2保留1的結(jié)果分析可知,靜態(tài)屬性和靜態(tài)代碼塊的執(zhí)行順序取決于編碼的順序。誰在前面就先執(zhí)行誰。

非靜態(tài)屬性的初始化

class Animal {  Animal(int age) {    System.out.println("Animal(" + age + ")");  }  void f(int age) {    System.out.println("f(" + age + ")");  }}public class NotStaticInit {  Animal a1;  Animal a2;  {    a1 = new Animal(1);    a2 = new Animal(2);    System.out.println("a1 & a2 initialized");  }  NotStaticInit() {    System.out.println("NotStaticInit");  }  public static void main(String[] args) {    System.out.println("Inside main()");    NotStaticInit x = new NotStaticInit();  }}

類似于靜態(tài)代碼塊,匿名代碼塊與非靜態(tài)屬性的初始化順序取決于編碼順序

繼承中的對象初始化過程

class Insect {  int i = 1;  int j;  Insect() {    prt("i = " + i + ", j = " + j);    j = 2;  }  static int x1 = prt("static Insect.x1 initialized");  static int prt(String s) {    System.out.println(s);    return 3;  }}public class Beetle extends Insect {  int k = prt("Beeklt.k initialized");  Beetle() {    prt("k = " + k);    prt("j = " + j);  }  static int x2 = prt("static Bootle.x2 initialized");  static int prt(String s) {    System.out.println(s);    return 4;  }  public static void main(String[] args) {    prt("Beetle constructor");    Beetle b = new Beetle();  }}

【運行結(jié)果】:

static Insect.x1 initialized

static Bootle.x2 initialized

Beetle constructor

i = 1, j = 0

Beeklt.k initialized

k = 4

j = 2

對Beetle運行Java時,發(fā)生的第一件事情是裝載程序到外面找到那個類。在裝載過程中,裝載程序發(fā)現(xiàn)一個基礎(chǔ)類,所以隨之將其載入。無論是否生成基礎(chǔ)類的對象,這一過程都將執(zhí)行。如果基礎(chǔ)類含有另一個基礎(chǔ)類,則另一個基礎(chǔ)類隨即也會載入,以此類推。接下來就在根基礎(chǔ)類中執(zhí)行static初始化,再在下一個衍生類中執(zhí)行,以此類推。這是因為衍生類的初始化可能要依賴于對基礎(chǔ)類成員的初始化。

當類都裝載完畢,就能創(chuàng)建對象。首先,這個對象中的所有基本數(shù)據(jù)類型都會設(shè)置成為他們的默認值,對象句柄設(shè)為null。然后執(zhí)行基礎(chǔ)類的構(gòu)建器。這種情況是自動完成的(衍生類的構(gòu)造函數(shù)中默認調(diào)用了super(),也可以通過super指定基類的構(gòu)建器)。基礎(chǔ)類構(gòu)建器完成后,衍生類實例變量就會按本來的順序得到初始化,然后執(zhí)行構(gòu)建器的剩余的主體部分。

總結(jié)對象創(chuàng)建的過程:

    靜態(tài)只在類加載的時候執(zhí)行且只執(zhí)行一次;

    非靜態(tài)只有在實例化的時候執(zhí)行,每次創(chuàng)建對象都執(zhí)行;

    靜態(tài)在非靜態(tài)之前執(zhí)行,基類靜態(tài)優(yōu)先于衍生類靜態(tài)執(zhí)行;

    靜態(tài)屬性和靜態(tài)代碼塊的執(zhí)行屬性取決于它們在類中的位置,誰在前先執(zhí)行誰;

    非靜態(tài)屬性和構(gòu)造塊的執(zhí)行順序取決于它們在類中的位置,誰在前執(zhí)行誰。

總結(jié)

通過上面的介紹,我們對Java中初始化對象的幾種方式以及通過何種方式執(zhí)行初始化代碼有了了解,同時也對何種情況下我們可能會使用到未經(jīng)初始化的變量進行了介紹。在對這些問題有了詳細的了解之后,就可以在編碼中規(guī)避一些風險,保證一個對象在可見之前是完全被初始化的。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 长乐市| 延边| 乌拉特前旗| 清水河县| 阿克苏市| 津市市| 开原市| 武安市| 龙里县| 武定县| 梅州市| 苍山县| 绵竹市| 福贡县| 潼南县| 麻城市| 莲花县| 万荣县| 东宁县| 中超| 丁青县| 石嘴山市| 奉新县| 文化| 闽侯县| 利川市| 美姑县| 塔城市| 长宁区| 漳州市| 苍梧县| 洮南市| 黄山市| 清徐县| 固阳县| 广州市| 通海县| 仲巴县| 略阳县| 阳西县| 东方市|