Thinking In Java 讀書筆記

==========================

create by wythe             2016/2/15 21:49

在看TIJ之前,已經(jīng)有了C/C++的一點基礎(chǔ)。最近因為參加學(xué)校的軟件編程比賽,做移動端的app,馬馬虎虎算是弄完了。在做得過程發(fā)現(xiàn)自己的java不熟悉(菜的一筆),所以閑時就看看這本經(jīng)典,做些筆記

一 、 Introduction to Object
  • 主數(shù)據(jù)類型(Primitive Type)
類型 大小 默認值
byte 8 bits (byte)0
char 16 bits '\u0000'(null)
boolean 1 bit false
short 16 bits (short)0
int 32 bits 0
long 64 bits 0L
float 64 bits 0.0f
double 64 bits 0.0d

若主數(shù)據(jù)類型屬于一個類成員,則會以上述的默認值初始化。但是局部變量會得到隨機值
99

二 、 Everything is Object
  • String str = new String("hello world") str為句柄

    Java通過句柄(str)來操作對象;
    句柄(str)在它的作用域(Scope)終點自動銷毀,然而句柄指向的對象還占據(jù)內(nèi)存空間;

  • 內(nèi)存
類型 作用
寄存器(Registers) 我們沒有直接控制權(quán),只能由編譯器分配
堆棧(The stack) 對象句柄的儲存的地方
堆(The heap) 對象的儲存地方
  • 注意點

如果您的main()用package語句封裝到一個文件里,那么必須在程序名前面指定完整的包裹名稱,否則不能運行程序。

三 、 Operator
  • ==和!=運算符

關(guān)系運算符==和!=也適用于所有對象。下面是一個例子:

//:
Equivalence.java public class Equivalence { 
     public static void main(String[] args) {     
              Integer n1 = new Integer(47);    
              Integer n2 = new Integer(47);     
              System.out.println(n1 == n2);     
              System.out.println(n1 != n2);  
     }
} ///:~ 

其中,表達式System.out.println(n1 == n2)
可打印出內(nèi)部的布爾比較結(jié)果。一般人都會認為輸出結(jié)果肯定先是true,再是false,因為兩個Integer對象都是相同的。但盡管對象的內(nèi)容相同,句柄卻是不同的,而==和!=比較的正好就是對象句柄。所以輸出結(jié)果實際上先是false,再是true。這自然會使第一次接觸的人感到驚奇。 若想對比兩個對象的實際內(nèi)容是否相同,又該如何操作呢?此時,必須使用所有對象都適用的特殊方法equals()。但這個方法不適用于“主類型”,那些類型直接使用==和!=即可。由于equals()的默認行為是比較句柄。所以除非在自己的新類中改變了equals(),否則不可能表現(xiàn)出我們希望的行為

  • 移位運算符

1、左移位運算符(<<)能將運算符左邊的運算對象向左移動運算符右側(cè)指定的位數(shù)
(在低位補0);
2、“有符號”右移位運算符(>>)則將運算符左邊的運算對象向右移動運算符右側(cè)指定
的位數(shù)?!坝蟹枴庇乙莆贿\算符使用了“符號擴展”:若值為正,則在高位插入0;若值為負,則在高位插入1;
3、Java也添加了一種“無符號”右移位運算符(>>>),它使用了“零擴展”:無論正負,都在高位插入0;

  • 主數(shù)據(jù)類型(int、long etc.)的二進制為補碼形式,用以下代碼驗證
//:Main.java
//Test for Learning Java
package com.company;
import java.util.*;
public class Main {
    public static void main(String[] args) {
    // write your code here
        int i = -1;
        printIntBinary(i);
        printIntBinary(i>>3);
        printIntBinary(i>>>3);
    }
    static void printIntBinary(int a){
        for(int j = 31; j >= 0; --j) {
            if((( 1 << j ) & a ) != 0)
                System.out.print("1");
            else
                System.out.print("0");
        }
        System.out.println();
    }
}
///:The end~

結(jié)果:


結(jié)果
  • javadoc sample.class

通過代碼的注釋,自動生成api文檔 教程

四 、 Initialization & Clean up
  • 對象初始化

static變量在非static變量前初始化
示例:

class Man{
    static int cnt;
    String name;
    //static區(qū)塊用于初始化static變量
    static{
        cnt=1;
    }
    //非靜態(tài)變量的初始化區(qū)塊,支持"匿名內(nèi)部類"的初始化
    {
        name = "Mike";
    }
    Man(){
        cnt++;
    }
}
  • 數(shù)組初始化

1、主數(shù)據(jù)類型(int、char etc.):表達式int[] a = new int[size]產(chǎn)生長度為sizeint數(shù)組,初始化值為默認值0.
2、對象:表達式Interger[] a = new Interger[size]產(chǎn)生一個句柄數(shù)組,具體的對象空間未分配。此時,數(shù)組元素的值為null。通過a[i] = new Interger(2)來關(guān)聯(lián)對象.

  • 多維數(shù)組

多維數(shù)組可以任意指定各維的大小
示例:

int [][][] a = new int[randInt()][][];
for(int i = 0; i < a.length; ++i){
     a[i] = new int[randInt()][];
     for(int j = 0; j < a[i].length; ++j){
          a[i][j] = new int[randInt()];
          for(int k = 0; k < a[i][j].length; ++k)
                a[i][j][k] = i*j*k;
      }
}
  • finalize()方法

Java提供了一個名為finalize()的方法,我們可以在自己類中定義它。它的工作原理:當垃圾收集器準備好釋放對象占用的儲存空間,它會首先調(diào)用finalize(),而且只有在下一次垃圾收集過程中,才會真正回收對象內(nèi)存。因此,可以用finalize()在垃圾收集期間進行一些重要的清除工作
示例:

//: initialization/TerminationCondition.java 
// Using finalize() to detect an object that 
// hasn’t been properly cleaned up.  
class Book {
    boolean checkedOut = false;
    Book(boolean checkOut) {
        checkedOut = checkOut;
    }
    void checkIn() {
        checkedOut = false;
    }
    protected void finalize() {
        if(checkedOut)
            System.out.println("Error: checked out");
// Normally, you’ll also do this:     
// super.finalize(); 
// Call the base-class version   
    }
}
public class TerminationCondition {
    public static void main(String[] args) {
        Book novel = new Book(true);
// Proper cleanup:  
        novel.checkIn();
// Drop the reference, forget to clean up:     
        new Book(true);
        // Force garbage collection & finalization:    
        System.gc();
    }
}
 /* Output: Error: checked out *///:~
五 、Access Control
  • 修飾符

1、friendly默認的訪問修飾符,它不是顯式的,不用特意來使用它。它指明可在包內(nèi)訪問,包外不可訪問。
2、protected在包內(nèi)訪問上與friendly一致。但protected可訪問性比friendly強。

可看以下圖片,紅色為語法錯誤


Package1

Package2
六 、Reusing Classes
  • final關(guān)鍵字

1、自變量final:例如,
void sampleMethod(final sampleClass s)中,無法改變自變量s句柄的指向(對象);
2、空白final:例如,

class blankFinal{
        final int i; 
        blankFinal(){
            i = 1;
        }
}

在對象初始化時,對final進行正確的賦值;

七、 Polymorphism
  • 多形性實例

//:Main.java
//Test for Learning Java
package com.company;
import com.company.tools.*;
class Instrument{
public void play(){
CustomPrint.print("Instrument~");
}
}
class Wind extends Instrument{
public void play(){
CustomPrint.print("Wind~");
}
}
class Brass extends Instrument{
public void play(){
CustomPrint.print("Brass~");
}
}
class Brass2 extends Brass{
public void play(){
CustomPrint.print("Brass2~");
}
}
public class Main {
public static void tune(Instrument isn){
isn.play();
}
public static void main(String[] args) {
Brass brass = new Brass();
Brass2 brass2 = new Brass2();
tune(brass);
tune(brass2);
}
}
///:The end~

![結(jié)果](http://upload-images.jianshu.io/upload_images/1623908-565bb364a569d2df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如果,
將上述的`play()`方法,加上static關(guān)鍵字`public static void play()`,則結(jié)果是:
![結(jié)果](http://upload-images.jianshu.io/upload_images/1623908-76d9edf55c437f8d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

- 接口
>***1、接口介紹***
1)接口不規(guī)定方法主體;
2)接口可以聲明**基本數(shù)據(jù)類型**的數(shù)據(jù)成員,它們都***默認***為static 和final;
3)與類相似,我們可在interface關(guān)鍵字的前面添加一個 public關(guān)鍵字(但只有接口定義于同名的一個文件內(nèi));或者將其省略,營造一種“friendly”狀態(tài);
4)接口中的方法聲明默認為 public。所以在實現(xiàn)一個接口的時候,來自接口的方法***必須***定義成public。不然它們會默認為“friendly"
就像這樣,

interface Instrument5 {
// Compile-time constant:
int i = 5; // static & final
// Cannot have method definitions:
void play(); // Automatically public
String what();
void adjust();
}

接口也具有多形性。下面這段代碼的結(jié)果和`多形性實例`的結(jié)果一致:

//:Main.java
//Test for Learning Java
package com.company;
import com.company.tools.*;
interface Instrument{
void play();
}
class Wind implements Instrument {
public void play(){
CustomPrint.print("Wind~");
}
}
class Brass implements Instrument {
public void play(){
CustomPrint.print("Brass~");
}
}
class Brass2 extends Brass{
public void play(){
CustomPrint.print("Brass2~");
}
}
public class Main {
public static void tune(Instrument isn){
isn.play();
}
public static void main(String[] args) {
Brass brass = new Brass();
Brass2 brass2 = new Brass2();
tune(brass);
tune(brass2);
}
}
///:The end~

**2、接口實現(xiàn)“多重繼承”**
>就像這樣,`class samlpe implements interface1,interface2,interface3`。sample可以將類型上溯至interface1,interface2,interface3中的任意一種。下面是一個實例:

//: Adventure.java
// Multiple interfaces import java.util.*;
interface CanFight { void fight(); }
interface CanSwim { void swim(); }
interface CanFly { void fly(); }
class ActionCharacter { public void fight() {} }
class Hero extends ActionCharacter
implements CanFight, CanSwim, CanFly {
public void swim() {}
public void fly() {}
}
class Adventure {
static void t(CanFight x) {
x.fight();
}
static void u(CanSwim x) {
x.swim();
}
static void v(CanFly x) {
x.fly();
}
static void w(ActionCharacter x) {
x.fight();
}
public static void main(String[] args) {
Hero i = new Hero();
t(i); // Treat it as a CanFight
t(i); // Treat it as a CanSwim
v(i); // Treat it as a CanFly
w(i); // Treat it as an ActionCharacter
}
} ///:~

**3、接口能夠繼承接口**
>像這樣`interface sample extends interface1,interface2,interface3`,形成更豐富的新接口
**4、接口產(chǎn)生枚舉數(shù)組**
>就像這樣,

public interface Months{
int
JANUARY = 1, FEBRUARY = 2, MARCH = 3,
APRIL = 4, MAY = 5, JUNE = 6, JULY = 7,
AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10,
NOVEMBER = 11, DESEMBER = 12;
}

接口內(nèi)的基本數(shù)據(jù)類型默認為***final*** **&** ***static***,可以***Months.JANUARY***的方式訪問。

- 內(nèi)部類
>**1、內(nèi)部類,一個被定義在現(xiàn)有類內(nèi)部的新類。**
像這樣,

public class Parcel1 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
public Contents cont(){
return new Contens();
}
public Destination to(){
return new Destination();
}
// Using inner classes looks just like
// using any other class, within Parcel1:
public void ship(String dest) {
Contents c = new Contents();
Destination d = new Destination(dest);
}
public void ship2(String dest){
Contents c = cont();
Destination d = to(dest);
}
public static void main(String[] args) {
Parcel1 p = new Parcel1();
p.ship("Tanzania");
Parcel.Contents c = p.cont();
}
}

**2、可在方法或者if語句等的作用域內(nèi)內(nèi)嵌一個內(nèi)部類,但是這個內(nèi)部類僅限在這個作用域內(nèi)使用**
**3、匿名類,方法尾部return一個內(nèi)部類**
像這樣,

public Content cont(){
return new Content(){
private int i = 0;
public int value(){return i;};
}
}

new 表達式返回的句柄會自動上溯到Content,由此,可以重寫Content的方法來隱藏實現(xiàn)細節(jié)1-·
**4、當一個新類繼承一個外部類時,外部類內(nèi)嵌的內(nèi)部類不會被自動繼承。因此,無法再新類中簡單地覆蓋內(nèi)部類**
實例:

//: BigEgg.java
// An inner class cannot be overriden
// like a method
class Egg {
protected class Yolk {
public Yolk() {
System.out.println("Egg.Yolk()");
}
}
private Yolk y;
public Egg() {
System.out.println("New Egg()");
y = new Yolk();
}
}
public class BigEgg extends Egg {
public class Yolk {
public Yolk() {
System.out.println("BigEgg.Yolk()");
}
}
public static void main(String[] args) {
new BigEgg();
}
} ///:~

輸出:New Egg( )
          Egg.Yolk( )
**5、可以用“外部類.內(nèi)部類”的方式來繼承內(nèi)部類,并可用這種方法來覆蓋父類內(nèi)部類的方法**
下面是例子:

//: BigEgg2.java
// Proper inheritance of an inner class
class Egg2 {
protected class Yolk {
public Yolk() {
System.out.println("Egg2.Yolk()");
}
public void f() {
System.out.println("Egg2.Yolk.f()");
}
}
private Yolk y = new Yolk();
public Egg2() {
System.out.println("New Egg2()");
}
public void insertYolk(Yolk yy) { y = yy; }
public void g() { y.f(); }
}
public class BigEgg2 extends Egg2 {
public class Yolk extends Egg2.Yolk {
public Yolk() {
System.out.println("BigEgg2.Yolk()");
}
public void f() {
System.out.println("BigEgg2.Yolk.f()");
}
}
public BigEgg2() { insertYolk(new Yolk()); }
public static void main(String[] args) {
Egg2 e2 = new BigEgg2();
e2.g();
}
} ///:~

輸出:   Egg2.Yolk()
          New Egg2()
          Egg2.Yolk()
          BigEgg2.Yolk()
          BigEgg2.Yolk.f()

#####八、Honding Your Objects
- continue配合標簽使用,可以連跳多級循環(huán)
>```
retry:
    while(true){
        int t=
                (int)(Math.random()*flav.length);
        for(int j=0;j<i;j++)
            if(picks[j]==t)continue retry;
    }
  • 命令行下編譯運行sample.java
    //cd 到com文件夾的上一級(如果是在IED(IJ)中生成的)

javac sample.java
//文件不含包名
java sample
//如果文件包含“package com.package”,則
java com.package.sample

還需要注意,“CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar”。其中,".;"表示當前路徑

九、Strings
  • StringBuilder
  • 正則表達式

String mp = "\w+@(\w+\.)+[A-Za-z]{2,14}";
String mail = "vicent@fzu.edu.cn";
Pattern p = Pattern.compile(mp);
Matcher m = p.matcher(mail);

十、 Runtime Type Indente
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,155評論 3 425
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,635評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,255評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,646評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,838評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,399評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,146評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,338評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,565評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,059評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,296評論 2 376

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,731評論 18 399
  • 多態(tài) 任何域的訪問操作都將有編譯器解析,如果某個方法是靜態(tài)的,它的行為就不具有多態(tài)性 java默認對象的銷毀順序與...
    yueyue_projects閱讀 971評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,814評論 18 139
  • 【程序1】 題目:古典問題:有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子長到第三個月后每個月又生一對兔...
    葉總韓閱讀 5,149評論 0 41
  • 一不留神竟然都已經(jīng)工作四年多了,儼然已經(jīng)成為了即將被后浪拍死在沙灘上的年紀。臉上的肥肉不知不覺爬上來,時刻提醒...
    TommyHu閱讀 308評論 0 2