final修飾的對象初始化時分兩種情況:
第一種:修飾成員對象時有3種初始化方式:
- 1,在定義變量時直接賦值
- 2,聲明完變量后在構造方法中為其賦值
- 3,聲明完變量后在構造代碼塊中為其賦值
第二種:修飾類對象(靜態對象)
- 1,在定義類變量時直接賦值
- 2,在靜態代碼塊中賦值
下面我們建立一個例子看看詳細情況:
public class TestFinal {
// 一、使用Final修飾符修飾的類的特點:該類不能有子類;
//
// 二、使用Final修飾符修飾的對象的特點:該對象的引用地址不能改變;
//
// 三、使用Final修飾符修飾的方法的特點:該方法不能被重寫;
//
// 四、使用Final修飾符修飾的變量的特點:該變量會變成常亮,值不能被改變。
//-----------------成員變量------------------//
//初始化方式一,在定義變量時直接賦值
private final int i = 5;
private final SysUser sysUser = new SysUser();
private final Book book = new Book();
//初始化方式二,聲明完變量后在構造方法中為其賦值
//如果采用用這種方式,那么每個構造方法中都要有j賦值的語句
private final int j;
private final Book book1;
public TestFinal() {
j = 5;
book1=new Book("三國演義","羅貫中");
// book=book1;
// book.setName("111");
// book.setAuthor("2222");
}
//如果取消該構造方法的注釋,程序就會報錯,因為它沒有為j和book1賦值
/*public TestFinal(String str) {
}*/
public TestFinal(String str) {
// 為了方便我們可以這樣寫
this();
}
//下面的代碼同樣會報錯,因為對j重復賦值
// public TestFinal(String str1, String str2) {
// this();
// j = 3;
// }
//初始化方式三,聲明完變量后在構造代碼塊中為其賦值
//如果采用此方式,就不能在構造方法中再次為其賦值
//構造代碼塊中的代碼會在構造函數之前執行,如果在構造函數中再次賦值,
//就會造成final變量的重復賦值
private final int k;
private final Book book2;
{
k = 5;
book2 = new Book("紅樓夢","曹雪芹");
}
//-----------------類變量(靜態變量)------------------//
//初始化方式一,在定義類變量時直接賦值
public final static int p = 5;
public final static Book book3 = new Book("水滸傳","施耐庵");
//初始化方式二,在靜態代碼塊中賦值
//成員變量可以在構造函數中賦值,但是類變量卻不可以。
public final static int q;
public final static Book book4;
static {
q = 5;
book4 = new Book("西游記","吳承恩");
}
//因為成員變量屬於對象獨有,每個對象創建時只會調用一次構造函數,
//因為可以保證該成員變量只被初始化一次;
//而類變量是該類的所有對象共有,每個對象創建時都會對該變量賦值
//這樣就會造成變量的重復賦值。
}