Java編程思想 (1~10)

【注:此博客旨在從《Java編程思想》這本書的目錄結構上來檢驗本身的Java基礎知識,只爲筆記之用】java

第一章 對象導論編程

1.萬物皆對象
2.程序就是對象的集合
3.每一個對象都是由其它對象所構成的
4.每一個對象都擁有其類型
5.同一個類型的對象能夠接收一樣的消息數組

簡單來講:對象具備狀態,行爲和標識服務器

每一個對象都是也給服務提供者,它經過使用其餘對象提供的服務來完成本身服務閉包

在Java語言中是單根繼承併發

1.9 容器》java中指List,Map,Set
  1.91 參數化類型》泛型 eg:List<String> list=new ArrayList<String>();app

1.10 對象的建立和生命週期》靜態方式建立對象:在編寫程序時就知道對象的確切數量,生命週期和類型,通常分配在堆棧或靜態存儲區域
動態方式建立對象:在堆(heap)的內存池中動態建立對象
在生命週期的控制上,在堆棧上建立對象的語言,編譯器能夠肯定對象的存活時間並自動銷燬,而在堆(heap)上建立對象,編譯器
卻不能正確的控制對象的生命週期。因此C++只能經過編程的方式來控制對象的生命週期,而Java由於提供了「垃圾回收機制」,它能夠自動
的控制對象的銷燬。
Java的這一能力主要得益於全部的對象都繼承Object而且只能一種方式建立對象(在用new 在堆上建立)這兩個特效框架

1.11異常處理:處理錯誤》Exceptionide

1.12併發編程》共享資源函數

1.13Java和Internet》客戶端/服務器 Javascript Actionscript 企業內部網(Intranet內聯網)/互聯網(Internet)

 

第二章
2.1 用引用操做對象》引用類型
2.2 必須由你建立全部對象》

  2.2.1 對象存儲位置:寄存器(位於CPU內部);堆棧(爲RAM隨機訪問存儲器中); 堆(也位於RAM中); 常量存儲(直接存儲在
代碼內部); 非RAM存儲

  2.2.3 Java中的數組:當建立一個數組對象時,實際上就是建立了一個引用數組,而且每一個引用都會被自動初始化爲null
            當建立一個基本數據類型的數組,也會在內存中所有初始化爲零。

    public static void main(String[] args) {
        int[] test = new int[3];//基本數據類型數組
        for (int i : test) {
            System.out.println(i);
        }
        Integer[] tem = new Integer[3];//引用類型數組
        for (Integer integer : tem) {
            System.out.println(integer);
        }
    }

結果:

0
0
0
null
null
null

 

2.2.3 Java中的數組:當建立一個數組對象時,實際上就是建立了一個引用數組,而且每一個引用都會被自動初始化爲null
當建立一個基本數據類型的數組,也會在內存中所有初始化爲零。

2.32 對象的做用域:在Java中用new建立的對象,只要你須要就會一直保存下去;即使超出了它的做用域,可是由於它是
引用類型,因此它一直存在只是沒法訪問吧!至於防止內存溢出的問題,就是Java垃圾回收機制控制

2.4 建立新的數據類型:類
2.4.1 字段和方法

2.5 方法、參數和返回值
  2.5.1 參數列表
2.6 構建一個Java程序
  2.6.1 名字可見性》命名空間 ;域名反過來
  2.6.2 運用其餘構件》import
  2.6.3 static關鍵字
2.7 你的第一個Java程序
  2.7.1 編譯和運行
2.8 註釋和嵌入式文檔
  2.8.1 註釋文檔
  2.8.2 語法
  2.8.3 嵌入式HTML

 

  2.8.4 一些標籤示例》@see引用其餘類;{@link package.class#member label};{@docRoot};{@inheritDoc};@version;@anthor;@since
@param;@return;@throws;@deprecated

   /**
     * Returns the cause of this throwable or {@code null} if the
     * cause is nonexistent or unknown.  (The cause is the throwable that
     * caused this throwable to get thrown.)
     *
     * <p>This implementation returns the cause that was supplied via one of
     * the constructors requiring a {@code Throwable}, or that was set after
     * creation with the {@link #initCause(Throwable)} method.  While it is
     * typically unnecessary to override this method, a subclass can override
     * it to return a cause set by some other means.  This is appropriate for
     * a "legacy chained throwable" that predates the addition of chained
     * exceptions to {@code Throwable}.  Note that it is <i>not</i>
     * necessary to override any of the {@code PrintStackTrace} methods,
     * all of which invoke the {@code getCause} method to determine the
     * cause of a throwable.
     *示例:{@link #getClass()}
     * @return  the cause of this throwable or {@code null} if the
     *          cause is nonexistent or unknown.
     * @since 1.4
     */
    public synchronized Throwable getCause() {
        return (cause==this ? null : cause);
    }

  2.8.5 文檔示例

2.9 編碼風格》類名首字母大寫 「駝峯命名法」

第三者 操做符
3.1 更簡單的打印語句》System.Out.println("Hello word");
3.2 使用Java操做符》+ - * /
3.3 優先級
3.4 賦值
  3.4.1 方法調用中的別名問題》方法引用傳參衍生出來的問題
3.5 算術操做符
  3.5.1 一元加、減操做符》++; --
3.6 自動遞增和遞減
3.7 關係操做符 》 >; < ;>=; <=
  3.7.1 測試對象的等價性
3.8 邏輯操做符》 「與(&&)」「或(||)」「非(!)」
  3.8.1 短路 》在與運算中第一個表達式爲false總體爲false,後面的表達式將再也不執行;或運算中第一個表達式爲true整
體爲true,後面的表達式也不會在執行了。
3.9 直接常量
  3.9.1 指數記數法
3.10 按位操做符》 「&」 「|」 「&=」「|=」
3.11 移位操做符》「>>」「<<」「>>=」「<<=」「>>>=」
3.12 三元操做符》 exp1?exp2:exp3;
3.13 字符串操做符+和+=
3.14 使用操做時常犯的錯誤
3.15 類型轉換操做符
  3.15.1 截尾和舍入
  3.15.2 提高》在作算術運算或按位運算時只要類型比int小,在運算前會自動轉換成int;若是是float與double值相乘,結
果double;若是是int和long值相加,則結果爲long.
3.16 Java沒有sizeOf》由於Java才建立對象是不須要知道該類型的大小
3.17 操做符小結

第四章
4.1 true和false
4.2 if-else
4.3 迭代
  4.3.1 while和do-while
  4.3.2 for
  4.3.3 逗號操做符》for(exp1,exp2,....;判斷表達式;exp3,exp4,.....)
4.4 Foreach語法
4.5 return
4.6 break和continue
4.7 臭名昭著的goto
4.8 switch》根據整數表達式的值,選擇case分支去執行

第五章
5.1 用構造函數確保初始化
5.2 方法重載
  5.2.1 區分重載方法》重載方法的方法名相同,可是參數類型列表不一樣/參數順序不一樣
  5.2.2 涉及基本類型的重載》傳入的實際參數小於方法接受的基本類型參數,他就會被
自動提高知足該類型的參數,好比:方法f(int i),而傳入的是short,那麼實際參數就會 被轉換爲int;可是
若是傳入的實際參數較大,那麼必須手動執行類型轉化
  5.2.3 以返回值區分重載方法》根據返回值區分重載是行不通的
5.3 默認構造函數》無參構造函數
5.4 this關鍵字
  5.4.1 在構造函數中調用構造函數
  5.4.2 static的含義》非靜態方法能夠調用靜態方法;可是靜態方法不能調用非靜態方法
5.5 清理:終結處理和垃圾回收
  5.5.1 finalize()的用途何在》爲了回收程序再也不使用的內存
  5.5.2 你必須實施清理》若是Java虛擬機(JVM)並未面臨內存耗盡的狀況,它是不會浪費時
間去執行垃圾回收以恢復內存的
  5.5.3 終結條件
  5.5.4 垃圾回收器如何工做》與加載器操做有關的技術被稱爲"即時"(Just-In_Time,JIT)
編譯器的技術。這種技術能夠把程序所有或部分翻譯成本地機器代碼,程序的運行速度所以就會獲得提高。
當須要裝載某個類時,編譯器會先找到其.class文件,而後將該類的字節碼裝入內存。此時,有兩種方案:
第一種,讓JIT編譯全部代碼,可是這種方式散落的加載動做會飛更多的時間;而且會增長肯可執行代碼的長
度,從而下降程序速度
另外一種方案:JIT只在必要的時候才編譯代碼;新版的JDK中的Java HotSpot技術就是採用相似的方法,代碼每
次執行的時候都會作一些優化,因此執行的次數越多它的速度就越快

5.6 成員初始化
  5.6.1 指定初始化
5.7 構造器初始化
  5.7.1 初始化順序
  5.7.2 靜態數據的初始化
  5.7.3 顯式的靜態初始化》靜態塊;靜態子句
  5.7.4 非靜態實例初始化
5.8 數組初始化
  5.8.1 可變參數列表》在重載方法中最好不要使用可變參數或者只在一個版本上使用
5.9 枚舉類型》enum

第六章 訪問權限控制
6.1 包:庫單元
  6.1.1 代碼組織
  6.1.2 建立獨一無二的包名
  6.1.3 定製工具庫
  6.1.4 用import改變行爲
  6.1.5 對使用包的忠告

6.2 Java訪問權限修飾詞
  6.2.1 包訪問權限》默認訪問權限沒有任何關鍵字即包訪問權限,包內其餘類可見包外不可見
  6.2.2 public:接口訪問權限
  6.2.3 private:你沒法訪問
  6.2.4 protected;繼承訪問權限
6.3 接口和實現
6.4 類的訪問權限》限制:1.每一個Java文件中只能有一個public類 2.public類的名稱必須徹底與Java文
件的文件名徹底同樣

第七章 複用類

7.1 組合語法
7.2 繼承語法
  7.2.1 初始化基類
7.3 代理》代理模式
7.4 結合使用組合和繼承
  7.4.1 確保正確清理
  7.4.2 名稱屏蔽
7.5 在組合和繼承之間選擇
7.6 protected關鍵字
7.7 向上轉型
  7.7.1爲何稱爲向上轉型
  7.7.2再論組合和繼承
7.8 final關鍵字
  7.8.1 final數據
  7.8.2 final方法》使用final方法的緣由有兩個:第一個緣由是防止任何繼承類修改該方法的定義;
第二個緣由是效率,早期被聲明爲final的方法在編譯時對該方法的調用都會轉化爲內嵌調用
  7.8.3 final類》當某個類被final修飾時表示該類不能被繼承

  7.8.4 有final的忠告

7.9 初始化及類加載》類的代碼在初次使用時才加載 即建立類的對一個對象時;尤爲是在訪問static成員時也會發生加載類代碼
  7.9.1 繼承與初始化

第八章 多態

8.1 再論向上轉型
  8.1.2 忘記對象類型
8.2 起色
  8.2.1 方法調用綁定
  8.2.2 產生正確的行爲
  8.2.3 可擴展性
  8.2.4 缺陷:"覆蓋"私有方法》因爲沒法訪問基類中的private方法,因此繼承類也沒法重載或覆寫
基類中的private方法。因此在繼承類中最好不要使用和基類private方法同名的名字
  8.2.5 缺陷:域與靜態方法》只有普通方法調用能夠多態

8.3 構造器和多態
  8.3.1 構造器的調用順序
  8.3.2 繼承與清理》在清理動手,能夠交給Java的垃圾回收器;若是確實須要作特殊清理,那麼能夠本身定義方法,
調用該方法進行清理
  8.3.3 構造器內部的多態方法和行爲》在編寫構造函數是儘量用簡單的方法是對象進入正常狀態;若是能夠的
話,避免調用其它方法
8.4 協變返回類型》能夠用基類類型去接收一個返回子類類型的方法返回值
8.5 用繼承進行設計
  8.5.1 純繼承與擴展
  8.5.2 向下轉型與運行類型識別

第9章 接口

9.1 抽象類和抽象方法
9.2 接口
interface Instructment{

  //編譯時常量
  int VALUE=6;//static &final
  void play(int i);
  void adjust();
}

9.3 徹底解耦
9.4 Java中的多重繼承》一個類能夠implements多個interface
9.5 經過繼承來擴展接口》一個接口能夠經過extends繼承另外一個接口
  9.5.1 組合接口時的名字衝突
9.6 適配接口
9.7 接口中的域
  9.7.1 初始化接口中的域
9.8 嵌套接口
9.9 接口與工廠

第十章

內部類的共性:
(1)內部類仍然是一個獨立的類,編譯以後內部類會被編譯成獨立的.class文件,可是前面冠之外部類的類名和$符號
(2)內部類不能用普通的方式訪問。內部類是外部類的一個成員,所以內部類能夠自由地訪問外部類的成員變量,不管
是不是private
(3)內部類聲明成靜態的,就不能隨便的訪問外部類的成員變量,此時內部類只能訪問外部類的靜態成員變量

10.1 建立內部類

        public class Parcel{
            class Contents{
                private int =1;
                public int value(){return i;}
            }
            //Using inner classes looks just like
            //using any other class,within parcel
            public c ship(){
                Contents c=new Contents();
                return c;
            }
            public static void main(String[] args){
                Parcel p=new Parcel();
                Parcel.Contents=p.ship();
            }
            
        }

10.2 連接到外部類》內部類自動擁有能夠訪問到外部類中的成員的

public class Sequence{
        private Object[] items;
        private int next=0;
        public Sequence(int size){
            items=new Object[size];
        }
        private class SequenceSelector{
            private int i=0;
            public boolean end(){
                return i=items.length;//
            }
            public void next(){
                i++;
            }
        }
        public SequenceSelector selector(){
            return new SequenceSelector();
        }
        
        public static void main(String[] args){
            Sequence seq=new Sequence();
            Sequence.SequenceSelector=seq.selector();
        }        
    }

10.3 使用.this與.new
在內部類中引用外部類對象,使用"外部類.this";建立某個內部類對象時須要使用外部類對象的引用+「.new」,使用形式"外部類對象.new"

    public class DotThis{
        void f(){}
        public class Inner{
            public DotThis outer(){
                return DotThis.this;
            }
        }
        public Inner inner(){return new Inner();}
        public static void main(String[] args){
            DotThis dt=new DotThis();
            DotThis.Inner dti=dt.new Inner();
            dti.outer().f();
        }
    }

在沒有建立外部類對象前不能建立內部類對象的,由於內部類對象暗地裏是關聯到它的外部類對象上的。可是對於嵌套類(靜態內部類),
就不須要對外部類對象的引用

10.4 內部類與向上轉型

public interface Destination{
    String readLabel();
}
public interface Contents{
    int value();
}

class Parcel{
    private class PContents implements Contents{
        public int value(){return 10;}
    }
    
    protected class PDestination implements Destination{
        public String readLabel(){
            return "Hello word";
        }
    }
    
    public PContent contents(){
        return new PContents();
    }
    public PDestination destination(){
        return new PDestination();
    }
}
public class TestParcel{
    public static void main(String[] args){
        Parcel p=new Parcel();
        Contents c=p.contents();
        Destination d=p.destination();
    }
}

10.5 在方法和做用域內的內部類

//方法內部類(又稱局部內部類)
public class Parcel{
    //方法
    public Destination destination(){
        //方法內部類
        class PInner implements Destination{
            public String say(){
                return "Hello word!";
            }
        }
        return new PInner();
    }
    
    public static void main(String[] args){
        Parcel p=new Parcel();
        Destination d=p.destination();
    }
}
//做用域內部類
public class Parcel{
    public void fun(boolean b){
        if(b){
            //做用域內部類
            class Inner{
                private String id;
                Inner(String id){
                    this.id=id;
                }
                public String say(){}
            }
            new Inner().say();
        }
    }
    public static void main(String[] args){
        Parcel p=new Parcel();
        p.fun(true);
    }
}

10.6 匿名內部類

abstract class Base{
        public Base(int i){
            print("Base constructor ");
        }
        public abstract void f();
    }
    public class Anonymous{
        public static Base getBase(int i){//這裏的i參數傳遞給了匿名類的基類構造函數,
        //並無在匿名類內部使用
            return new Base(i){
                public void f(){
                    print("Anonymout f()");
                }
            }
        }
        
        public Destination destination(final String dest,final float price){
            return new Destination(){
                private int cost;
                {
                    cost=Math.round(price);//當直接在匿名類直接使用參數時必須加final                    
                }
                private String str=dest;
            }
            
        }
        
        public static void main(String[] args){
            Base base=getBase(4);
            base.f();
        }
    }

  10.6.1在訪工廠方法

interface Game{boolean move();}
interface GameFactory{Game getGame();}

class Checker implements Game{
    public boolean move(){...}
    public static GameFactory factory=new GameFactory(){
        public Game getGame(){return new Checker()};
    };
}
class Chess implements Game{
    public boolean move(){....}
    public static GameFactory factory=new GameFactory(){
        public Game getGame(){return new Chess()};
    };
}
public class TestGames{
    public static void playGame(GameFactory g){
        Game game=g.getGame();
        g.move();
    }
    
    public static void main(String[] args){
        playGame(Checker.factory);
        playGame(Chess.factory);
    }    
}

10.7 嵌套類
內部類聲明爲static就是嵌套類,與普通內部類的區別

(1)要建立嵌套類對象不須要外部類對象;

(2)不能從嵌套類的對象中訪問非靜態的外部類對象

(3)普通內部類不能有static數據和static字段

    class Outer{
        static class Inner{}
    }
    class Test {
        public static void main(String[] args){
            Outer.Inner n = new Outer.Inner();
        }
    }

  10.7.1 接口內部類

    public interface Outter{
        void fun();
        class Inner implements Outter{
            public void fun(){}
            public static void main(String[] args){
                new Inner().fun();
            }
        }
    }

  10.7.2 從多層嵌套類中訪問外部類的成員》一個內部類被嵌套多少層並不重要,它均可以透明地訪問全部它所嵌入的外部類的全部成員

class Outter1{
    private void f(){}
    class Outter2{
        private void g(){}
        class Inner{
            void h(){
                g();
                f();
            }
        }
    }    
}
public class Test{
    public static void main(String[] args){
        Outter1 o1=new Outter1();
        Outter1.Outter2 o2=o1.new Outter2();
        Outter1.Outter2.Inner i=o2.new Inner();
        i.h();
    }
}

10.8 爲何須要內部類
  10.8.1 閉包 

  閉包(closure)是一個可調用的對象,它記錄了一些信息,這些信息來自於建立它的做用域。經過這個定義能夠看出在Java語言中,
內部類起着閉包的角色做用,由於它不只包含了外部類對象建立內部類的做用域信息,還自動擁有一個指向此外部類對象的應用,
在此做用域內,內部類有權操做全部的成員,包括private成員。

package com.test.demo;

interface Incrementable {
    void increment();
}

class Callee1 implements Incrementable {
    private int i = 0;

    public void increment() {
        i++;
        System.out.println(i);
    }
}

class MyIncrement {
    public void increment() {// 注意這裏已經有了一個increment方法
        System.out.println("\nOther operation");
    }

    static void f(MyIncrement mi) {
        mi.increment();
    }
}
//由於Callee2繼承MyIncrement中已經又increment方法了
//若是Callee2想要implements(實現) Incrementable
//那麼就須要使用內部類
class Callee2 extends MyIncrement {
    private int i = 0;

    public void increment() {
        super.increment();
        i++;
        System.err.println(i);
    }

    private class ClosureDe implements Incrementable {
        @Override
        public void increment() {
            Callee2.this.increment();//這裏調用外部類的increment方法
        }
    }

    Incrementable getCallbackReference() {
        return new ClosureDe();
    }
}

class Caller {
    private Incrementable callbackreference;

    public Caller(Incrementable inc) {
        this.callbackreference = inc;
    }

    void go() {
        callbackreference.increment();
    }
}

public class Closure {
    public static void main(String[] args) {
        Callee1 c1 = new Callee1();
        Caller caller1 = new Caller(c1);
        caller1.go();
        caller1.go();

        Callee2 c2 = new Callee2();
        MyIncrement.f(c2);
        Caller caller2 = new Caller(c2.getCallbackReference());
        caller2.go();
        caller2.go();
    }
}

 

  10.8.2 內部類與控制框架
10.9 內部類的繼承

package com.test.demo;
class WithInner {
class Inner {}
}

public class InheritInner extends WithInner.Inner {
  public InheritInner(WithInner wi) {
wi.super();
}
public InheritInner() {
new WithInner().super();
}
public static void main(String[] args) {
   WithInner wi = new WithInner();
   InheritInner ii = new InheritInner(wi);
  }
}

在繼承內部類時若是繼續使用默認構造器會報錯,並且不能只傳遞一個指向外部類對象的引用。此時必須在構造器內使用以下語法:
  外部類對象.super();
這樣才提供了必要的引用,才能夠編譯經過

10.10 內部類能夠被覆蓋嗎》當繼承某個外部類時,內部類並無發生什麼變化。內部類是徹底獨立的兩個實體,各自在本身的命名空間內
10.11 局部內部類》局部內部類不能有訪問說明符,由於它不是外部類的一部分;可是它能夠訪問當前代碼代碼塊中的常量,以及此外部類的全部成員
10.12 內部類標識符》內部類也會生成一個.class文件。這些文件的命名規則是:外部類的名字+「$」+內部類的名字;若是是匿名內部類編譯器也會產生一個數字做爲你其標識

相關文章
相關標籤/搜索