小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

《HeadundefinedFirstundefinedJava》讀書筆記

 容心居 2019-07-24

從大學(xué)課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)到工作中的一些小功能調(diào)整,自己的Java水平一直是會(huì)點(diǎn)語法+面向搜索引擎編程級(jí)別。想要更加深入地學(xué)習(xí)Java的東西,但是Java圣經(jīng)又太厚,自己也不是特別擅長(zhǎng)看這些技術(shù)書籍的人,在別人的建議下選了《Head First Java》來看。
縱觀全書,這本書的重點(diǎn)在Java的基礎(chǔ)語法、對(duì)象、多態(tài)與繼承等概念上的講解(講得挺好的),對(duì)于一些異常處理、線程、IO、網(wǎng)絡(luò)方面更多是簡(jiǎn)單的介紹,并沒有深入講解。
原本想通過這本書學(xué)習(xí)線程方面的概念,為閱讀其他更加深入講解線程方面的文章打下基礎(chǔ),但是似乎無法達(dá)到目的。
盡管如此,我還是通過閱讀這本書學(xué)習(xí)的到了一些新的東西。這篇筆記,就是為了整理記錄這些新學(xué)到的知識(shí),以鞏固我對(duì)這些知識(shí)的掌握。


對(duì)象的聲明、創(chuàng)建與賦值

當(dāng)我們聲明一個(gè)非基本數(shù)據(jù)類型的變量時(shí),我們通常這樣寫:
Dog myDog = new Dog();
在這簡(jiǎn)單的一行代碼中,其實(shí)包含了三個(gè)步驟:

// 1. 聲明一個(gè)Dog類型的引用變量Dog myDog// 2. 創(chuàng)建Dog對(duì)象 new Dog// 3. 將創(chuàng)建的Dog對(duì)象,賦值給myDog這個(gè)引用變量Dog myDog = new Dog(); 

所以,當(dāng)我們聲明對(duì)象數(shù)據(jù)的時(shí)候,實(shí)際上是聲明了該對(duì)象的引用變量數(shù)據(jù)。


對(duì)象的生存空間

在Java虛擬機(jī)驅(qū)動(dòng)的時(shí)候,會(huì)從底層操作系統(tǒng)獲得一塊內(nèi)存來執(zhí)行Java程序。在內(nèi)存中,要關(guān)注這兩塊區(qū)域:對(duì)象的生存空間堆和方法調(diào)用及變量生存的空間棧。

  • 堆又被稱為可垃圾回收的堆,一旦對(duì)象失去了引用,就有可能被回收。

  • 實(shí)例變量是被聲明在類而不是方法中,所以實(shí)例變量存在于所屬的對(duì)象中(堆中)。

  • 而局部變量則是被生命在方法中,所以局部變量存在于棧中。


賦值與引用的例子

Book a = new Book();
Book b = new Book();  //這里有兩個(gè)引用變量,兩個(gè)對(duì)象Book c = a;  //此時(shí)有三個(gè)引用變量,兩個(gè)引用變量,c與a指向同一個(gè)對(duì)象b = a; // 此時(shí)b也與a指向同一個(gè)對(duì)象,b原本指向的對(duì)象失去了引用,處于可回收狀態(tài) 

繼承與多態(tài)

  • 子類會(huì)繼承父類除了private的所有實(shí)例變量和方法。

  • 運(yùn)用多態(tài)時(shí),引用類型可以是實(shí)際對(duì)象類的父類;參數(shù)和返回類型都可以多態(tài)。

Animal[] animals = new Animal[5];
animals[0] = new Dog();
animals[1] = new Cat();

Class Vet{    public void giveshot(Animal a){
    a.makeNoise();
}

Vet vet = new Vet();
v.giveshot(new Dog());
}
  • 父類的方法可以在子類中被覆蓋,但是標(biāo)記了final的方法無法被覆蓋。

  • 一個(gè)類只能繼承一個(gè)父類。但是繼承可以是多層繼承。B繼承A,C繼承B,則C也是A的子類。

  • 所有對(duì)象都是Object的子類,可以用Object來實(shí)現(xiàn)多態(tài),但是一般不這樣做。

Object o = new Dog();int i = o.hashCode();  // 可行,因?yàn)镺bject本身有hashCode()方法o.makeNoise(); // 不可執(zhí)行,因?yàn)榇藭r(shí)o的引用類型是Object,Object沒有makeNoise()方法,無法執(zhí)行。Animal a = (Dog) o;
a.makeNoise(); // 可行,當(dāng)o賦值給a時(shí)進(jìn)行了類型轉(zhuǎn)換,Dog是Animal的子類,所以可以賦值成功。Animal有makeNoise()方法,所以可以執(zhí)行
  • 當(dāng)一個(gè)類執(zhí)行構(gòu)造函數(shù)時(shí),會(huì)先執(zhí)行完父類的構(gòu)造函數(shù)。如果存在多層繼承,就會(huì)一直到最初的父類執(zhí)行完構(gòu)造函數(shù),才一層一層向下執(zhí)行。

  • 在子類的構(gòu)造函數(shù)中執(zhí)行父類的構(gòu)造函數(shù):

public Dog(String name){//調(diào)用父類的構(gòu)造函數(shù)super();
}
  • 當(dāng)子類的構(gòu)造函數(shù)中沒喲調(diào)用super()時(shí),編譯器在編譯時(shí)在我們編寫的構(gòu)造函數(shù)中添加super();

  • 當(dāng)我們想重載一個(gè)構(gòu)造函數(shù),但是又調(diào)用到這個(gè)構(gòu)造函數(shù)時(shí):

Class Dog{
    String name;    public Dog(){        // 調(diào)用了有一個(gè)String參數(shù)的構(gòu)造函數(shù)
        this("myDog");
    }    public Dog(String name){        //調(diào)用父類的構(gòu)造函數(shù)
        super();
    }
}
  • 在構(gòu)造函數(shù)中,this()和super()都要存在于構(gòu)造函數(shù)的第一行,不得同時(shí)存在。


接口與抽象類

  • 抽象類沒有實(shí)體,抽象類中的方法也沒有方法體。

  • 接口類是抽象類,抽象類不一定是接口類。

  • implements接口后,要實(shí)現(xiàn)該接口類的所有方法。

  • extends只能extend一個(gè)父類,implements可以implement好多個(gè)接口。

靜態(tài)方法

  • 非靜態(tài)方法需要有實(shí)例才能調(diào)用,靜態(tài)方法不需要實(shí)例,直接以類名就可以調(diào)用。

// 非靜態(tài)方法Dog d = new Dog();
d.makeNoise();// 靜態(tài)方法Math.min(3,7);
  • 靜態(tài)方法中沒有實(shí)例變量,也不允許調(diào)用非靜態(tài)的變量。

  • 靜態(tài)方法不允許調(diào)用費(fèi)靜態(tài)的方法。

  • 靜態(tài)變量是同一個(gè)類所有實(shí)例共享的。每一個(gè)實(shí)例都有一個(gè)屬于自己的實(shí)例變量。但靜態(tài)變量是每個(gè)類一個(gè)。這里可能會(huì)有多個(gè)實(shí)例對(duì)同一個(gè)靜態(tài)變量同時(shí)進(jìn)行修改的問題。

  • 靜態(tài)變量會(huì)在該類有任何靜態(tài)方法執(zhí)行之前就初始化。

  • final的變量代表值無法被改變,final的方法代表無法被覆蓋,final的類代表無法被繼承。以下例子來自java提高篇(十五)-----關(guān)鍵字final

public class Person {    private String name;

    Person(String name){        this.name = name;
    }    
    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }
}public class FinalTest {    private final String final_01 = "chenssy";    //編譯期常量,必須要進(jìn)行初始化,且不可更改
    private final String final_02;                //構(gòu)造器常量,在實(shí)例化一個(gè)對(duì)象時(shí)被初始化
    
    private static Random random = new Random();    private final int final_03 = random.nextInt(50);    //使用隨機(jī)數(shù)來進(jìn)行初始化
    
    //引用
    public final Person final_04 = new Person("chen_ssy");    //final指向引用數(shù)據(jù)類型
    
    FinalTest(String final_02){        this.final_02 = final_02;
    }    
    public String toString(){        return "final_01 = " + final_01 +"   final_02 = " + final_02 + "   final_03 = " + final_03 +               "   final_04 = " + final_04.getName();
    }    
    public static void main(String[] args) {
        System.out.println("------------第一次創(chuàng)建對(duì)象------------");
        FinalTest final1 = new FinalTest("cm");
        System.out.println(final1);
        System.out.println("------------第二次創(chuàng)建對(duì)象------------");
        FinalTest final2 = new FinalTest("zj");
        System.out.println(final2);
        System.out.println("------------修改引用對(duì)象--------------");
        final2.final_04.setName("chenssy");
        System.out.println(final2);
    }
}

------------------
Output:
------------第一次創(chuàng)建對(duì)象------------
final_01 = chenssy   final_02 = cm   final_03 = 34   final_04 = chen_ssy
------------第二次創(chuàng)建對(duì)象------------
final_01 = chenssy   final_02 = zj   final_03 = 46   final_04 = chen_ssy
------------修改引用對(duì)象--------------
final_01 = chenssy   final_02 = zj   final_03 = 46   final_04 = chenssy

異常處理

  • finally塊中的代碼無論有無異常都會(huì)執(zhí)行。

  • 異常也是多態(tài)的,Exception是所有異常的父類。

  • 異??梢詔hrows 也可以 try/catch。

  • 可以為每個(gè)不同的異常編寫不同的catch塊,但是要注意子類要放在父類之前catch

try{ // do somethings} catch (DogException de){  //deal DogException} catch (AnimalException ae){  //deal AnimalException}// 如果AnimalException的catch塊在DogException之前,那么DogException也會(huì)被AnimalException的catch塊捕獲,就不會(huì)落到后面的DogException的catch塊了。

內(nèi)部類

  • 內(nèi)部類可以使用外部類的所有方法和變量,包括標(biāo)記為private的。

  • 內(nèi)部類的實(shí)例一定會(huì)綁定在外部類的實(shí)例上。

  • 內(nèi)部類的其中一個(gè)適用場(chǎng)景:一個(gè)界面,需要監(jiān)聽多個(gè)按鈕點(diǎn)擊事件并且不同按鈕的點(diǎn)擊事件有不同的響應(yīng)。


IO

IO這一章簡(jiǎn)單地講了一下文件操作,著重講了序列化的內(nèi)容。
其實(shí)這章序列化說得不好,建議看這里Java 序列化的高級(jí)認(rèn)識(shí)

  • 序列化程序會(huì)對(duì)象相關(guān)的所有東西都存儲(chǔ)起來,被對(duì)象的實(shí)例變量所引用的所有對(duì)象都會(huì)被實(shí)例化。

  • 如果要讓類能夠被序列化,必須實(shí)現(xiàn)Serializable

  • 如果某實(shí)例變量不能/不應(yīng)該被序列化,就把他標(biāo)記為瞬時(shí)的(transient),這樣序列化時(shí)候,程序會(huì)將它跳過。到了解序列化的時(shí)候這個(gè)引用變量會(huì)被置為null。

  • 解序列化的時(shí)候,所有的類都必須讓JVM找到。

  • 解序列化時(shí),新的對(duì)象會(huì)被分配到堆上,但構(gòu)造函數(shù)不會(huì)執(zhí)行。

  • 如果對(duì)象在繼承樹上的有不可序列化的祖先類,則該不可序列化類以及在它之上的類的構(gòu)造函數(shù)(就算是可序列化的類)就會(huì)執(zhí)行。從第一個(gè)不可序列化的父類開始,之上的類都會(huì)回到初始狀態(tài)。

  • 靜態(tài)文件不會(huì)被序列化。

  • 序列化標(biāo)志:如果在解序列化之前,類已經(jīng)發(fā)生了修改,可能會(huì)導(dǎo)致解序列化失敗。

會(huì)損害序列化的修改:

  • 刪除實(shí)例變量

  • 改變實(shí)例變量的類型

  • 將非瞬時(shí)的實(shí)例變量改為瞬時(shí)的

  • 改變繼承的繼承層次

  • 將類從可序列化改為不可序列化

  • 將實(shí)例變量變成靜態(tài)的

較為安全的修改:

  • 加入新的實(shí)例變量(還原時(shí)取默認(rèn)值)

  • 在繼承層次中加入新的類

  • 在繼承層次中刪除類

  • 將實(shí)例變量從瞬時(shí)改為非瞬時(shí)

  • 一致的序列化ID有利于保證反序列化的成功。


網(wǎng)絡(luò)通信與多線程

  • 服務(wù)器與客戶端通過socket連接來溝通。

  • 當(dāng)ServerSocket接收到請(qǐng)求時(shí),會(huì)在另外的一個(gè)端口做一個(gè)socket連接來處理客戶端的請(qǐng)求。

  • 線程代表獨(dú)立的執(zhí)行空間。

  • 多線程同時(shí)執(zhí)行時(shí),實(shí)際上是多個(gè)線程隨機(jī)輪流執(zhí)行的。

  • 線程進(jìn)入可執(zhí)行狀態(tài)時(shí),會(huì)在執(zhí)行中和可執(zhí)行這兩種狀態(tài)中切換。但是也可能進(jìn)入堵塞狀態(tài)。堵塞狀態(tài)可能是閑置、等待其他縣城完成、等待串流數(shù)據(jù)、等待被占用的對(duì)象等原因引起的。

  • 構(gòu)造線程時(shí)需要傳入一個(gè)任務(wù)對(duì)象,這個(gè)任務(wù)對(duì)象需要實(shí)現(xiàn)Runnable接口。

  • 并發(fā):不同線程對(duì)同一個(gè)對(duì)象同時(shí)進(jìn)行處理,可能引起問題。

  • 鎖:要讓對(duì)象在線程上有足夠的安全性,就要對(duì)不可分割執(zhí)行的指令上鎖(同步化)。

  • 如果線程嘗試進(jìn)入同步化的方法,必須取得對(duì)象的鑰匙如果鑰匙被別的線程拿走了,線程只能等待。

  • 如果兩個(gè)線程互相持有對(duì)方正在等待執(zhí)行的方法的鑰匙,就會(huì)發(fā)生死鎖。

    死鎖

集合與排序

  • 常見的集合類型,有序的集合中的元素必須是可比較的,Comparable的:

  • TreeSet:有序且防止重復(fù)的集合。

  • HashMap:Key-Value集合,Key不可重復(fù)

  • HashSet:防止重復(fù)的集合,可快速找到相符元素

  • LinkedList:針對(duì)經(jīng)常插入或者刪除中間元素所涉及的高效率集合(不如ArrayList實(shí)用)

  • LinkedHashMap:可記住元素插入順序,可設(shè)定依照原宿上次存儲(chǔ)先后來排序的HashMap。

  • ArrayList中的sort()方法,可進(jìn)行已實(shí)現(xiàn)了Comparable接口的類的排序,也可以使用實(shí)現(xiàn)了Comparator接口的內(nèi)部類來進(jìn)行排序。

// 實(shí)現(xiàn)Comparable接口class Song inplements Comparable<Song>{
    public int compareTo(Song s){       return title. compareTo(s.getTitle());
   }
}// 實(shí)現(xiàn)Comparatorclass Song{class ArtistCompare implements Comparator<Song>{
    public int Compare (Song one, Song two){          return one.getArtist().compareTo(two.getArtist());
    }


ArtistCompare artistCompare = new ArtistCompare();
    Collections.sort(songList, artistCompare);
}

}
  • 如果equal()被覆蓋過,hashCode()方法也應(yīng)該相應(yīng)覆蓋。

  • equal()默認(rèn)行為是執(zhí)行==的比較,即判斷兩個(gè)引用變量是否引用堆中的同一個(gè)對(duì)象。如果equals()沒有被覆蓋過,那么兩個(gè)對(duì)象永遠(yuǎn)不會(huì)被視為相等的。

  • a.equals(b)必須與a.hashCode()==b.hashCode()等值,但a.hashCode()==b.hashCode() 不一定與a.equals(b)等值。

泛型

//這里的list僅接受ArrayList<Animal>public void takeThing(ArrayList<Animal> list) 

 //這里的list對(duì)象可以接受ArrayList<Dog>、ArrayList<Cat>等繼承Animal的對(duì)象的ArrayList// 泛型的extends等價(jià)于實(shí)體類的extends或者implementspublic <T extends Animal> void takeThing(ArrayList<T> list)//萬用字符也可以讓ArrayList接受Animal的子類// 使用萬用字符,能夠調(diào)用list中任何元素的方法,但是不能增加元素。public void takeAnimals(ArrayList<? extends Animal> animals){    for(Animal a:animals){
        a.eat();  //合法
    }
    animals.add(new Dog());  //不合法的操作}// 第二、第三種寫法執(zhí)行起來是一樣的,但是在一般用第二種,因?yàn)樾枰獋魅攵鄠€(gè)對(duì)象時(shí),第二種方法不需要多次聲明public <T extends Animal> void takeThing(ArrayList<T> one, ArrayList<T> two)

遠(yuǎn)端過程調(diào)用

遠(yuǎn)端過程調(diào)用

遠(yuǎn)端過程調(diào)用的過程:

  1. 啟動(dòng)RMI registry

  2. 遠(yuǎn)程服務(wù)被初始化(生成stub和skeleton)

  3. 遠(yuǎn)程服務(wù)向RMI registry注冊(cè)

  4. 客戶端查詢RMI registry

  5. 客戶端從RMI registry獲取stub

  6. 客戶端調(diào)用stub上的方法

  7. stub將方法的調(diào)用送到服務(wù)器上

  • 啟動(dòng)服務(wù)前應(yīng)先啟動(dòng)注冊(cè)器

  • 遠(yuǎn)程服務(wù)的參數(shù)和返回都需要做成可序列化

  • Jini--adaptive discovery:自動(dòng)注冊(cè)、知道接口名稱就可以自動(dòng)適配下發(fā)stub

  • Jini--self-healing networks:通過續(xù)約的方式確定服務(wù)的狀態(tài),超過續(xù)約時(shí)間不進(jìn)行續(xù)約就會(huì)任務(wù)該服務(wù)已離線。


碎片知識(shí)

  • 數(shù)據(jù)隱藏:將成員變量標(biāo)記為private,將getters、setters標(biāo)記為public。

  • 實(shí)例變量總會(huì)有默認(rèn)值:無論有沒有明確賦值或者調(diào)用setter,實(shí)例變量總會(huì)有默認(rèn)值。

integer --- 0
floating point --- 0.0
boolean --- false
reference --- null

  • ==:使用==來比較兩個(gè)基本數(shù)據(jù)類型或判斷兩個(gè)引用變量是否指向同一個(gè)對(duì)象。==可以用來比較任何類型的兩個(gè)變量,因?yàn)樗皇潜容^其中的字節(jié)組合。

  • equals():使用equals()來判斷兩個(gè)對(duì)象是否在意義上向相等

int a = 3;byte b =3;if(a == b){ 
// true}
Foo c = new Foo();
Foo d = new Foo();
Foo e = c;if(c == d){// false}if(c == e){// true}if(c.equals(d)){// true}
  • x++與++x:x++先執(zhí)行x+1,再執(zhí)行賦值;++x先執(zhí)行賦值,再執(zhí)行x+1

  • 長(zhǎng)運(yùn)算符(| &)與短運(yùn)算符(|| &&):

  • 在&&表達(dá)式中,左右兩邊都為true這個(gè)表達(dá)式返回true,當(dāng)左邊返回false時(shí),JVM不會(huì)執(zhí)行右邊的計(jì)算就直接返回false;

  • 在||表達(dá)式中,左右兩邊都為false這個(gè)表達(dá)式返回false,當(dāng)左邊返回true時(shí),JVM不會(huì)執(zhí)行右邊的計(jì)算就直接返回true;

  • & 和 | 在boolean表達(dá)式會(huì)強(qiáng)制JVM執(zhí)行兩邊的運(yùn)算,但一般長(zhǎng)表達(dá)是用在位運(yùn)算中。

  • 當(dāng)一個(gè)類沒有構(gòu)造方法時(shí),編譯器再編譯時(shí)會(huì)默認(rèn)加上一個(gè)無參的構(gòu)造方法。但是如果一個(gè)類已有一個(gè)構(gòu)造方法,則編譯器不會(huì)再加上無參的構(gòu)造方法。

  • 格式化說明

    格式化說明

需要拓展的知識(shí)點(diǎn)

// 位非 ~int x = 10;  //00001010x = ~x;  //11110101// 位與 & 、位或 |、位異或 ^int x = 10;  //00001010int x = 6;    //00000110// 位與 &: 兩位都是1返回1,否則返回0int a =x&y;  //00000010// 位或 |: 有一位為1就返回1,否則返回0int a =x&y;  //00001110// 位異或 ^: 位相同返回1,否則返回0int a =x&y;  //11110010// 移位運(yùn)算 左移<<,右移>>,無符號(hào)右移>>>,需要結(jié)合數(shù)據(jù)類型來看。int x = -11;  //11111011// 左移 1位,等于值*2,向左邊移動(dòng),并且在低位補(bǔ)0.int a= x<<1; //11110110// 右移1位,等于值/2,帶符號(hào)右移,若左操作數(shù)是正數(shù),則高位補(bǔ)“0”,若左操作數(shù)是負(fù)數(shù),則高位補(bǔ)“1”.int a= x>>1; //1111101// 無符號(hào)右移,無論左操作數(shù)是正數(shù)還是負(fù)數(shù),在高位都補(bǔ)“0”int a= x>>>1; //0111101
  • 不變性:String類型和包裝類都是不可變的。創(chuàng)建后就值就不可以改變。JVM中有一個(gè)String Pool,不受GC的影響。如果新建的String引用變量的值在String Pool中有相同值的對(duì)象,會(huì)直接引用這個(gè)對(duì)象,而不是新建一個(gè)String對(duì)象。

  • 斷言:執(zhí)行時(shí)沒有特殊設(shè)置JVM會(huì)自動(dòng)忽略斷言,運(yùn)行時(shí)打開JVM的斷言設(shè)置,則可以在不影響任意代碼的前提下進(jìn)行除錯(cuò)。

  • 靜態(tài)嵌套類:可以在沒有外層實(shí)例的情況下使用的類。

public class Outer{
    static class Inner{
        void do(){        // do somethings
        }
    }   class Test{
        public static void main (String args[]){
          Outer.Inner a = new Outer.Inner();
          a.do();
        }
    }
}
  • 非靜態(tài)的嵌套類是通常成為內(nèi)部類。

  • 匿名內(nèi)部類:

button.addActionListen(new ActionListen{    public void actionPerformed(ActionEvent e){    //  do somethings
    }
})
  • default與protected:default-同一個(gè)包內(nèi)可存取,protected-允許不同包的子類繼承它的成員。

  • 多維數(shù)組:int[][] a2d = new int[4][2]>>這里由5個(gè)數(shù)組組成。

    多維數(shù)組
  • 枚舉ENUM:Java 枚舉(enum) 詳解7種常見的用法

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多