1. 程式人生 > >Thinking in Java ---final關鍵字總結+初始化和類的載入

Thinking in Java ---final關鍵字總結+初始化和類的載入

final關鍵字既可以用來修飾基本變數,引用也可以用來修飾方法和類。在修飾不同的物件時有不同的含義,很容易搞混淆,在此做一個小結。瞭解一下繼承情況下變數的初始化和類的載入機制,也能讓我們對程式執行時發生的一切有一個全域性性的把握。

一。final關鍵字
1.1 final關鍵字修飾變數
final關鍵字類似於C++中的const關鍵字,當它修飾基本變數時表明該變數一旦被初始化為某一值就不能再被改變。當final用於修飾一個引用時情況有點不同,它只能表示該引用一旦初始化時指向某個物件,那麼這個引用的指向就不能再改變了,但是其指向的物件的值卻還是可以改變的,下面的程式示範了這一點。

package lkl;

public class Value {

      public int i;
      Value(int i){
          this.i=i;
      }
}


package lkl;

import java.util.Random;

public class FinalTest {

    public static Random rand = new Random(45);

    public final int valueOne=9;   ///final修飾普通變數
    public final int valueTwo = rand.nextInt(34
);///final修飾的普通變數,不一定要用常量賦值 public final Value val = new Value(1); ///final修飾引用 public static final int INT_1=10; ///final和static連用表示一個編譯時就可以確定的常量 public static void main(String[] args){ FinalTest ft=new FinalTest(); //ft.valueOne++; ///試圖修改final型基本變數的值,Error System.out.println(ft.valueTwo); ft.val.i++; ///
修改final引用指向物件的值是可以的
//ft.val=new Value(2);//試圖修改final修飾引用的指向,Error } }

上面的程式碼中還出現了static和final共同修飾一個變數的情況,這時這個變數只佔據一段不能被修改的儲存空間,稱為編譯時常量.
在Java中final型別的變數也可以不在宣告時就初始化,可以將初始化的過程放到構造器中(必須所有的構造器中都有初始化的語句),這樣也可以保證變數在使用前肯定會被初始化.這樣的好處在於可以根據不同的情況對final型變數賦不同的值.這種final變數被稱為”空白final”.
下面的程式碼示範了這種情況:

package lkl;

import java.util.Random;

public class FinalTest {

    public final int i;
    public final int j;
    public FinalTest(){
        i=0; j=0;
    }
    public FinalTest(int i,int j){
        this.i=i; this.j=j;
    }
    public static void main(String[] args){
        FinalTest ft=new FinalTest();
        FinalTest ft1 = new FinalTest(1,2);
        System.out.println("ft: i ,j "+ft.i+" "+ft.j);
        System.out.println("ft1:i,j "+ft1.i+" "+ft1.j);
    }
}

最後還有一種final用於修飾形參變數的用法,這時意味著你不能在方法中更改引數引用指向的物件.此時的形參只可讀而不可寫,如下面的程式碼所示:

package lkl;

import java.util.Random;

public class FinalTest {

     public Value with(final Value val){
         val= new Value(2); ///試圖改變val的指向,Error
         return val;
     }
     public Value w(final Value val){
         return val;
     }
     public int go(final int i){
         i++;///試圖改變i的值,Error
         return i;
     }
     public int f(final int i)
     {
          return i+1;
     }
    public static void main(String[] args){

    }
}

1.2 final修飾方法和類
final用於修飾方法,則表明不能被子類重寫(覆蓋).這樣可以保證在繼承中方法行為不變.父類中所有的private方法都是隱式指定為final的.對於private方法,如果我們在子類中定義一個與其完全一樣的方法,也不能叫做重寫,只是重寫定義了一個新的方法.但對於final修飾的方法,我們是不可以在子類中進行重寫.所以重寫只是針對在子類中可見的父類介面.

package lkl;

public class Base {

      private void f(){
          System.out.println("Base.private()");
      }
      public final void g(){
          System.out.println("Base.final()");
      }
}


package lkl;

public class OverringBase1 extends Base{

    private void f(){
        System.out.println("OverringBase1.f()");
    }
    public final void g(){ ///Error
        System.out.println("OverringBase1.g()");
    }
}

對於final修飾類來講就要簡單的多,我們只需要知道如果一個類被final修飾則該類不能被繼承就行了,當然此時該類中的所有的域都預設是final的.

二.初始化和類的載入.
Java中的每個類都會有它自己的編譯程式碼,然後如果我們想要使用這個類時,就需要載入這個編譯程式碼檔案.當一個類的第一個物件被宣告時,或者是類的static 變數被呼叫時,類就會被初始化,每個類只會被初始化一次.
如果一個類有基類,那麼在載入這個類的過程中就會先載入基類,如果這個基類還有父類,那麼也會先載入他的父類,如此.
在此過程中從最初的基類開始,所有類的static變數會被初始化.
對於其它變數的初始化:建立物件時,首先物件中的所有基本型別都會被設為預設值,物件的引用被設為null,然後如果有初始化塊,則初始化塊會被執行,最後再呼叫構造器進行初始化,變數會按其次序被初始化.下面的程式碼演示了初始化的流程:

package lkl;

public class Base {
    public int i=9; ///先指定一個預設值
    public int j;
    public int k;
    public int d;
    public Base(int x){
        j=i;
        i=x;    
        k=i;
    }
    {
        i=10; ///初始化塊
        d=i;
    }
    public static void main(String[] args){
        Base be =new Base(2);
        ///輸出的值說明初始化塊先被執行,然後再是構造器
        System.out.println(be.j+" "+" "+be.k+" "+be.d);
    }
}

相關推薦

Thinking in Java ---final關鍵字總結+初始載入

final關鍵字既可以用來修飾基本變數,引用也可以用來修飾方法和類。在修飾不同的物件時有不同的含義,很容易搞混淆,在此做一個小結。瞭解一下繼承情況下變數的初始化和類的載入機制,也能讓我們對程式執行時發生的一切有一個全域性性的把握。 一。final關鍵字

從一個例子看Java的資料初始載入

一、程式碼鎮帖 package javase.jvm; public class ClassInitTest { private static final String staticCodeBlock = " static code block ";

think in java--7.10初始載入的理解

1.在java中每個類都會編譯成一個獨立得檔案。該檔案只會在程式需要使用的時候才載入。可以說:類得程式碼在初次使用的時候才會載入。還有,當訪問static域或者方法時候,也會發生載入。初次使用之處也是static載入發生之處,所有的static物件和static方法都會在載入時按照程式順序載入,定義

[Think in java]靜態資料的初始

package com.test.two; public class Test4 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated

Thinking in java自讀筆記:HashMap,TreeMapHashtable

HashMap於HashTable的異同: 相同點:HashMap和Hashtabel的儲存元素都是鍵值對,實現原理都是雜湊表。 主要不同點: 1.繼承父類不同,Hashtable繼承與Dictionary(已廢棄),HashMap繼承於AbstractMap 2.Hashtable

thinking in java (三十) ----- IO之 FileReaderFileWriter

介紹 FileReader是用於讀取字元流的類,繼承於InputStreamReader,如果要讀取原始位元組流,需要使用InputStream。 FileWriter是用於寫入字元流的類,繼承於OutputStreamWriter,如果要寫入原始位元組流,需要使用Outptu

Java程式設計思想ch5 初始清理

5.1 用構造器初始化 new 類名() 將建立和初始化,綁在一起。 5.2 方法過載 5.4 this關鍵字 class Banana{void peel(int i)}{} public class BananaPeel{

Java之旅 (6) 初始清理

用建構函式保證初始化,JAVA的物件建立和初始化是同一個概念,你不能要這個而不要那個。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 方法的過載區分經過載的

final關鍵字 ——Thinking in Java學習筆記(十一)

final的使用情況一般分為三種:資料、方法、類 final資料 final修飾的資料表示值不可變,引用不能改變。其中,對資料的修飾又分為: 1、final成員變數:由final修飾的類成員變數,如果是基礎資料型別就表示不能改變它的值,但如果是已經初始化了的引用

Thinking in Java 第四版完整版 第五章練習題 初始與清理

Thinking in Java 第四版完整版 第五章練習題,記錄一下(jdk1.8.0) 1. /** * 練習1:建立一個類,它包含一個未初始化的String引用。驗證該引用被Java初始化成了null。 * @author admin11 * @date 2

Java基礎4——深入理解final關鍵字static關鍵字以及初始順序

深入理解final關鍵字和static關鍵字以及初始化順序 final關鍵字(基礎1中提到) final關鍵字可以修飾類、方法和引用。 修飾類,該類不能被繼承。並且這個類的物件在堆中分配記憶體後地址不可變。 修飾方法,方法不能被子類重寫。 修飾引用,引用無法改變,對於基本型別,無法修

final關鍵字(thinking in java)

final關鍵字由於語境(應用環境)不同,final關鍵字的含義可能會稍微產生一些差異。但它最一般的意思就是宣告“這個東西不能改變”。之所以要禁止改變,可能是考慮到兩方面的因素:設計或效率。由於這兩個原因頗有些區別,所以也許會造成final關鍵字的誤用。在接下去的小節裡,我們

Java中未給定初始值的基礎資料型別為什麼不能輸出 ——Thinking in Java學習筆記(二)

在java程式設計思想第二章節中有這麼一個練習題:定義一個類,給定兩個無初始值的int和char型別的數值,輸出兩個數的值,驗證int和char的初始值。 我第一次是這麼做的: public static void main(String[] args) { int i; char

thinking in java (十八) ----- 集合之Map(HashMap HashTable)總結

Map框架圖 Map概括 Map是鍵值對對映的抽象介面 AbstractMap實現了Map中的大部分介面,減少了Map實現類的重複程式碼 HashMap是基於拉鍊法實現的散列表,一般使用在單執行緒程式中 HashTable是基於拉鍊法

thinking in java (十七) ----- 集合之List總結

List概括 首先回顧一下關係圖 Lsit是一個介面,繼承與Collection介面,它代表的是有序的佇列 AbstractList是一個抽象類,它繼承於AbstractCollection,AbstractList實現List介面中除了size(),get(

thinking in java (四) ----- static與this關鍵字

static  static代表什麼 static表示“全域性”或者“靜態”的意思,用來修飾成員變數或者方法,也可以修飾程式碼塊。被static修飾的成員會在類載入的時候進行初始化與空間分配,被設定為靜態後,成員會被存放在靜態儲存空間,全域性共享一個值。因此訪問被st

thinking in java (二十二) ----- IO之序列

序列化的作用和用途 序列化,就是為了保持物件的狀態,而與之對應的反序列化,則可以把物件的狀態再讀取出來, 簡而言之:序列化/反序列化,是JAVA提供的一種專門用於儲存/恢復物件狀態的機制。 一般在以下幾種情況我們會使用序列化: 1.當你想把記憶體中的物件狀態儲存到

《物件建立過程中 例項的順序》摘自《Thinking in JAVA

最近一直在看《Thinking In JAVA》,裡面一些知識點自己平日裡還真沒有注意過: 譬如這部分:在例項化物件的過程,物件的各部分的初始化順序: 總結一下物件的建立過程,假如有個名為Dog的類: 1.即使沒有顯示的使用Static關鍵字,構造器實際上也是靜態方法,

看《Thinking in Java》的一點點總結

這兩天,看了《Thinking in Java》的兩章:異常和方法學,以及附錄B,有一點點小體會。 關於異常,一直都沒怎麼用,貌似就沒這個概念~~  555  或許還得構建的自己的一套異常系統,所以,一直總是想想而已,沒有真正的實踐起來~ 方法學和附錄B,最想說的是:

Thinking in Java》 And 《Effective Java》啃起來

大學 前言 技術 數據結構和算法 解決 一句話 定義 應該 太多的 前言   今天從京東入手了兩本書,《Thinking in Java》(第四版) 和 《Effective Java》(第二版)。都可以稱得上是硬書,需要慢慢啃的,預定計劃是在今年前把這兩本書啃完。哈哈,可