java 对象初始化_Java对象初始化
自動初始化(默認值)
一個類的所有基本數據成員都會得到初始化,運行下面的例子可以查看這些默認值:
classDefault{booleant;charc;byteb;shorts;inti;longl;floatf;doubled;public voidshow() {
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 classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
【運行結果】:
基本類型 初始化值
booleanfalse
char
byte0
short0
int0
long0
float0.0
double0.0
其中,char類型的默認值為空(null)。
對于非基本數據類型而言,對象的句柄也會被初始化:
classPerson {privateString name;//setter
}classDefault {
Person p;public voidshow() {
System.out.println("Person" +p);
}
}public classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
【運行結果】:
Personnull
可見,句柄初始化值為null。這就是說,如果沒有為p指定初始化值就調用類似于p.setName的方法,就會出現異常。
規定初始化
如果需要自己為變量賦一個初始值,可以在定義變量的同時賦值。
classDefault{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 voidshow() {
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 classInitValue {public static voidmain(String[] args) {
Default d= newDefault();
d.show();
}
}
甚至可以通過一個方法來進行初始化;
classPerson {int i =set();//...
}
這些方法也可以使用自變量:
classPerson {inti;int j =set(i);//...
}
構建器初始化
構建器進行初始化的優點是可以在運行期決定初始化值。例如:
classPerson {intage;
Person() {
age= 89;
}
}
age首先會初始化為0,然后變成89。對于所有基本類型以及對象的句柄,這種情況都是成立的。
初始化順序
在一個類里,初始化的順序是由變量在類內的定義順序決定的。即使變量定義大量遍布于方法定義的中間,那么變量仍然會在調用任何方法(包括構造函數)之前得到初始化。例如:
classPet {
Pet(intage) {
System.out.println("Pet(" + age + ")");
}
}classPerson {
Pet t1= new Pet(1);
Person() {
System.out.println("---Person()---");
t3= new Pet(33);
}
Pet t2= new Pet(2);voidshow() {
System.out.println("show----running");
}
Pet t3= new Pet(3);
}public classOrderOfInitialization {public static voidmain(String[] args) {
Person p= newPerson();
p.show();
}
}
【運行結果】:
Pet(1)
Pet(2)
Pet(3)
---Person()---
Pet(33)
show----running
上例中,雖然t1、t2、t3的定義遍布于類中,但是初始化的先后順序是由t1、t2、t3的定義順序決定的(自己動手調換t1、t2、t3看看結果),且初始化優先于構建器執行,當調用Person的構建器時,t3重新初始化。
靜態數據的初始化
如果數據是靜態的(static),同樣的過程也會執行。若屬于基本類型,而且未對其進行初始化,就會自動獲得自己的標準基本類型初始值;若它是指向一個對象的句柄,除非創建一個對象同它連接起來,否則得到一個空值(null)。如果在定義時初始化,采取的方式與非靜態值是不同的,這是因為static只有一個存儲區域。例如:
classBowl {
Bowl(intmarker) {
System.out.println("Bowl(" + marker + ")");
}void f(intmarker) {
System.out.println("f(" + marker + ")");
}
}classTable {static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
b2.f(1);
}void f2(intmarker) {
System.out.println("f2(" + marker + ")");
}static Bowl b2 = new Bowl(2);
}classCupboard {
Bowl b3= new Bowl(3);static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}void f3 (intmarker) {
System.out.println("f3(" + marker + ")");
}static Bowl b5 = new Bowl(5);
}public classStaticInitialization {public static voidmain(String[] args) {
System.out.println("Creating new Cupboard() in main");newCupboard();
System.out.println("Creating new Cupboard() in main");newCupboard();
t2.f2(1);
t3.f3(1);
}static Table t2 = newTable();static Cupboard t3 = newCupboard();
}
【運行結果】:
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)
靜態代碼塊
Java允許將其他static初始化工作劃分到類內一個特殊的代碼塊中,這種代碼塊的形式為static關鍵字,后面跟著一個方法主體,稱為靜態代碼塊。靜態代碼塊只有在第一次生成那個類的對象或首次訪問屬于那個類的static成員時執行。例如:
classPerson {
Person(intage) {
System.out.println("Person(" + age + ")");
}void f(intage) {
System.out.println("f(" + age + ")");
}
}classPersons {staticPerson p1;staticPerson p2;static{
p1= new Person(1);
p2= new Person(2);
}
Persons() {
System.out.println("Persons()");
}
}public classExplicitStatic {public static voidmain(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的行內訪問static對象p1的時候,或在行1被注釋而行2未被注釋是,用于Persons的static初始化模塊就會運行。若1和2都被注釋掉,則用于Persons的靜態代碼塊不會執行。
靜態屬性和靜態代碼塊執行的先后順序
classPerson {
Person(intage) {
System.out.println("Person("+age+")");
}
}classPersons {static Person p = new Person(2); //1
static{
p= new Person(3);
}static Person p = new Person(2); //2
}public classCompStaticInit {public static voidmain(String[] args) {
}static Persons x = newPersons();
}
根據注釋1保留2,注釋2保留1的結果分析可知,靜態屬性和靜態代碼塊的執行順序取決于編碼的順序。誰在前面就先執行誰。
非靜態屬性的初始化
classAnimal {
Animal(intage) {
System.out.println("Animal(" + age + ")");
}void f(intage) {
System.out.println("f(" + age + ")");
}
}public classNotStaticInit {
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 voidmain(String[] args) {
System.out.println("Inside main()");
NotStaticInit x= newNotStaticInit();
}
}
類似于靜態代碼塊,匿名代碼塊與非靜態屬性的初始化順序取決于編碼順序。
繼承中的對象初始化過程
classInsect {int i = 1;intj;
Insect() {
prt("i = " + i + ", j = " +j);
j= 2;
}static int x1 = prt("static Insect.x1 initialized");static intprt(String s) {
System.out.println(s);return 3;
}
}public class Beetle extendsInsect {int k = prt("Beeklt.k initialized");
Beetle() {
prt("k = " +k);
prt("j = " +j);
}static int x2 = prt("static Bootle.x2 initialized");static intprt(String s) {
System.out.println(s);return 4;
}public static voidmain(String[] args) {
prt("Beetle constructor");
Beetle b= newBeetle();
}
}
【運行結果】:
static Insect.x1 initialized
static Bootle.x2 initialized
Beetle constructor
i = 1, j = 0
Beeklt.k initialized
k = 4
j = 2
對Beetle運行Java時,發生的第一件事情是裝載程序到外面找到那個類。在裝載過程中,裝載程序發現一個基礎類,所以隨之將其載入。無論是否生成基礎類的對象,這一過程都將執行。如果基礎類含有另一個基礎類,則另一個基礎類隨即也會載入,以此類推。接下來就在根基礎類中執行static初始化,再在下一個衍生類中執行,以此類推。這是因為衍生類的初始化可能要依賴于對基礎類成員的初始化。
當類都裝載完畢,就能創建對象。首先,這個對象中的所有基本數據類型都會設置成為他們的默認值,對象句柄設為null。然后執行基礎類的構建器。這種情況是自動完成的(衍生類的構造函數中默認調用了super(),也可以通過super指定基類的構建器)。基礎類構建器完成后,衍生類實例變量就會按本來的順序得到初始化,然后執行構建器的剩余的主體部分。
總結對象創建的過程:
靜態只在類加載的時候執行且只執行一次;
非靜態只有在實例化的時候執行,每次創建對象都執行;
靜態在非靜態之前執行,基類靜態優先于衍生類靜態執行;
靜態屬性和靜態代碼塊的執行屬性取決于它們在類中的位置,誰在前先執行誰;
非靜態屬性和構造塊的執行順序取決于它們在類中的位置,誰在前執行誰。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的java 对象初始化_Java对象初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 第9章_Java基础第9章.p
- 下一篇: python3 sleep 并发_Pyt