《Java編程思想》第二章:一切都是對象

第二章:一切都是對象

若是咱們說另外一種不一樣的語言,那麼咱們就會發覺一個有些不一樣的世界。java

                                                                                     ——Luduing Wittgerstein(1889-1951)編程

Java是基於C++的,Java是一種更「純粹」的面向對象程序設計語言。數組

Java和C++都是混合/雜合型語言,雜合型語言容許多種編程風格。瀏覽器

C++之因此成爲一種雜合型語言主要是由於它支持與C語言的向後兼容。C++是C的一個超集。安全

Java中(幾乎)一切都是對象。bash

一、用引用操縱對象

每種編程語言都有本身的操縱內存中元素的方式。在Java中一切都被視爲對象,所以可採用單一固定的語法。儘管一切都看作對象,可是操縱的標識符其實是對象的一個「引用」(reference)。架構

例如:建立一個String的引用:併發

String s;

但這裏所建立的只是引用,並非對象。若是此時向s發送一個消息,就會返回一個運行時錯誤。此時s尚未與任何事物相關聯。所以安全的作法是:建立一個引用的同時便進行初始化。以下:app

String s=」asdf」;

這裏用到了Java語言的一個特性:字符串能夠用帶引號的文本初始化。編程語言

二、必須由你建立全部對象

一般用new關鍵字來建立一個對象,new關鍵字的意思是「給我一個新對象」。

前面的例子就能夠寫成以下:

String s = new String(「asdf」);

它不只表示「給我一個新的字符串」,並且經過提供一個初始化字符串,給出了怎樣產生這個String的信息。

除了String類型,Java提供了大量過剩的線程類型。重要的是,你能夠自行建立類型,這是Java程序設計中一項基本行爲。

1.存儲到什麼地方

有五個不一樣的地方能夠存儲數據:

寄存器:

位於處理器內部,最快的存儲區,數量有限,不能直接操做,根據需求進行分配,在程序中感受不到它的存在。

堆棧:

位於通用RAM(隨機訪問存儲器)中,經過堆棧指針分配和釋放內存,速度僅次於寄存器。存放於堆棧中的全部項必須明確其生命週期,便於指針移動,控制內存。對象的引用都存儲在堆棧,對象並不存儲在堆棧中。

堆:

也位於RAM區,用於存放對象。編譯器不須要知道存儲的數據在堆裏存活多長時間,當須要一個對象時,只需用new來建立便可,當執行這個代碼時,會自動在堆裏分配空間。用堆進行存儲分配和清理可能比用堆棧進行存儲分配須要更多的時間。

常量存儲:

常量值不會被改變,常量自己會和其餘部分隔離開,能夠選擇將其存放在ROM(只讀存儲器)中。

非RAM存儲:

若是數據徹底存活於程序以外,那麼它能夠不受程序的任何控制,在程序沒有運行時也能夠存在。

例如:流對象和持久化對象。

在流對象中,對象轉化成字節流,一般被髮送給另外一臺機器。

在持久化對象中,對象被存放於磁盤上。

這種存儲的特色:把對象轉化成能夠存放在其餘媒介上的事物,在須要時,可恢復成常規的、基於RAM的對象。

2.特例:基本類型

基本類型:不使用new來建立變量,而是建立一個並不是是引用的「自動」變量,這個變量直接存儲「值」,並保存在堆棧中。

Java要肯定每種基本類型所佔存儲空間的大小,它們的大小不會隨着機器硬件架構的變化而變化,這種不變性是Java程序更具可移植性的緣由之一。

基本數據類型 大小 最小值 最大值 包裝器類型
boolean - - - Boolean
cahr 16bit Unicode0 Unicode2^16-1 Character
byte 8bit -128 +127 Byte
short 16bits -2^15 +2^15-1 Short
int 32bits -2^31 +2^15-1 Interger
long 64bits -2^63 +2^63-1 Long
float 32bits IEEE754 IEEE754 Double
double 64bits IEEE754 IEEE754 Double
void - - - Void

由此能夠看出,基本類型有9種,一般只說前8種。

全部數值類型都有正負號,boolean類型所佔存儲空間的大小沒有明確指定,僅可以取true或false兩個值。

基本類型具備包裝器類,做用是能夠在堆中建立一個非基本類型的對象用來表示對應的基本類型。Java SE5提供了自動封箱/拆箱功能。

例如:

char c = ‘x’;
Character ch = new Character(c);
Character ch = new Character(‘x’);
Character ch = ‘x’;
char c = ch;

高精度數字

Java提供了兩個用於高精度計算的類:BigInteger和BigDecimal。將全部的運算符使用方法來代替,以速度換取了精度。

BigInteger支持任意精度的整數。

BigDecimal支持任何精度的定點數。

3.Java中的數組

幾乎全部的程序設計語言都支持數組。Java也支持,Java確保數組會被初始化,並且不能在他的範圍以外被訪問。這種範圍檢查基於每一個數組上少許的內存開銷以及運行時的下標檢查,由此換來的是安全性和高效。

當建立一個數組對象時,實際上就是建立了一個引用數組,而且會賦予默認值null,此時尚未關聯對象。在使用任何引用前,必須爲其指定一個對象;若是使用一個仍是null的引用,在運行時將會報錯。

三、永遠不須要銷燬對象

程序設計中變量的生命週期是很是重要的部分,變量生命週期的混亂每每會致使大量的程序bug。

1.做用域

做用域(scope)決定了在其內定義的變量名的可見性和生命週期。在做用域裏定義的變量只可用於做用域結束以前。Java中,做用域由花括號的位置決定。例如:

{
  int x = 12;
  {
    int q = 96;
  }
}

Java是一種自由格式(free-form)的語言,空格、製表符、換行都不會影響程序的執行結果。

Java中不容許下面這種方式聲明變量:

{
  int x = 12;
  {
    int x = 96;
  }
}

編譯器會報告變量x已經定義過,Java中認爲這樣會致使程序混亂。

2.對象的做用域

Java對象的生命週期和基本類型的生命週期是不同的。

當用new建立一個Java對象後,它的生命週期遠大於當前做用域,當前做用域只是限制了此對象的引用的生命週期,超出了當前做用域只是沒法再訪問此對象,此對象仍然存活於內存中。

Java中靠垃圾回收器,來監視對象,並釋放不在被引用的對象的內存空間。

因此對象的生命週期是從new開始,到垃圾回收器釋放其內存時結束。對象的生命週期不是隨着做用域的結束而結束。

四、建立新的數據類型:類

程序設計語言習慣用關鍵字class來表示類型,Java中也是使用class這個關鍵字來建立新類型的。例如:

class ATypeName{/* Class body goes here */}

上面已經建立好了一個類型,可使用new來建立這個對象。

ATypeName a = new ATypeName();

1.字段和方法

Java的類中設置兩種類型的元素:字段(數據成員)、方法(函數)。
字段能夠是任何類型的對象,能夠經過其引用與其進行通訊;也能夠是基本類型。
例如:

class DataOnly{
  int i;
  double d;
  boolean b;
  String s;
}

此時能夠建立這個類型的對象,並能夠給這個對象的字段賦值,例如:

DataOnly data = new DataOnly();
data.i =47;
data.d = 1.1;
data.b = false;
data.s = 「asdf」;
//修改字段的值
data.i= 50;

基本成員默認值:

若類的某個成員是基本數據類型,及時沒有進行初始化,Java也會自動賦予默認值。

boolean的默認值是false;char的默認值是’\u0000’(null);byte、short、int、long都是對應類型的0;float、double都是對應類型的0.0。

上述初始化的默認值不適用於局部變量,只能用於類的成員變量。

五、方法、參數和返回值

Java中習慣用方法這個術語來表示「作某些事情的方式」。

Java的方法決定了一個對象可以接收什麼樣的消息。方法的基本組成部分包括:名稱、參數、返回值和方法體。形式以下:

ReturnType methodName(Argument list){
  /* Method body */
}

返回類型描述的是在調用方法以後從方法返回的值。

參數列表給出了要傳給方法的信息的類型和名稱。

方法名和參數列表合起來稱爲方法簽名,能夠惟一的標識出一個方法。

Java中的方法只能做爲類的一部分來建立,方法只能經過對象才能被調用(static方法除外),且這個對象必須能執行這個方法調用。對象調用方法時,須要先列出對象名,緊接着是句點,而後是方法名和參數列表。例如:

objectName.methodName(arg1,arg2,arg3);

假設一個方法f(),不帶參數,返回類型是int,屬於a對象的類,那麼調用能夠以下這樣:

int x = a.f();

接收返回值的變量的類型必須和返回值類型兼容。

調用方法的行爲一般被稱爲發送消息給對象。

1.參數列表

方法的參數列表指定要傳遞給方法什麼樣的信息,這些信息採用的都是對象的形式,在參數列表中必須指定每一個被傳遞對象的類型及名字,這裏傳遞的實際上也是引用,而且引用的類型必須正確。

例如:

int storage(String s){
  return s.length() * 2;
}

return關鍵字的用法包括兩方面:首先他表明方法的結束。其次傳遞返回值。

若返回類型時void,return關鍵字的做用只是用來退出方法。若是返回值類型不是void,那麼不管在何處返回,編譯器都會強制返回一個正確類型的返回值。

能夠這樣認爲:大致上程序只是一系列帶有方法的對象組合,這些方法以其餘對象爲參數,併發送消息給其餘對象。

六、構建一個Java程序

1.名字可見性

名字管理對任何程序設計語言來講,都是一個重要的問題。

爲了給一個類庫生成不會與其餘名字混淆的名字,Java建議反轉域名,句點用來表明子目錄的劃分。

Java1.0和Java1.1中,擴展名com、edu、org、net等約定爲大寫形式。Java2中包名都是用小寫了。

這種機制意味着全部的文件都可以自動存活於他們本身的名字空間內,並且同一個文件內的每一個類都有惟一的標識符。

2.運用其餘構件

import指示編譯器導入一個包,也就是一個類庫,或者一個類。

例如:導入一個類。

improt java.util.ArrayList;

導入一個包。

improt java.util.*;

3.static關鍵字

static關鍵字能夠兩個情形的問題:

一種是,只想爲某特定域分配單一存儲空間,而不去考慮究竟要建立多少對象,甚至根本就不建立對象。

另外一種是,但願某個方法不與包含它的類的任何對象關聯在一塊兒。

即便從未建立某個類的對象,也能夠調用其static方法或訪問其static域。

Java中也用到了類數據和類方法兩個術語,表明那些數據和方法只是做爲整個類,而不是類的某個特定對象而存在的。

只需將static關鍵字放在定義以前,就能夠將字段或方法設定爲static。

例如:

class StaticTest{
  static int i = 47;
}

引用static變量有兩種方法:能夠經過一個對象去引用;也能夠經過類名直接引用。

例如:

StaticTest.i++;
StaticTest s = new StaticTest();
s.i++;

使用類名是引用static變量的首先方法,某些狀況下這種方式能夠爲編譯器進行優化提供了更好的機會。

static做用於字段時,改變了數據建立的方法,static字段對每一個類來講都只有一份存儲空間,而非static字段則是對每一個對象有一個存儲空間。

定義靜態方法的定義方式與靜態變量相似,例如:

class Incrementable{
  static void increment(){ StaticTest.i++; }
}

靜態方法的調用和靜態變量的調用是同樣的。

static方法的一個重要用法就是在不建立任何對象的前提下就能夠調用它。這一點在main()方法上是標誌性的應用。(main()方法是程序的入口)

七、你的第一個Java程序

最後,讓咱們編寫一個完整的程序示例:

import java.util.*;
public class HelloDate {
    public static void main(String[] args) {
        System.out.println("Hello, it's: ");
        System.out.println(new Date());
    }
}

java.lang是默認導入到每一個Java文件中的,因此它的全部類均可以被直接使用。

java.lang包裏沒有Date類,能夠經過Java JDK文檔中選擇「Tree」,查詢類屬於哪一個類庫,也但是直接使用查詢功能搜索Date類,就會看到它屬於java.util.Date,因此使用import

java.util.*導入類庫才能使用,或者使用import java.util.Date進行導入。

System類有不少屬性,out成員變量是此類的一個靜態的PrintStream對象,println()方法是PrintStream類的一個方法,此方法的意思是將傳入的數據打印到控制檯並換行。
類的名字必須和文件名相同。若是你要建立一個獨立運行的程序,那麼文件中必須存在一個類與文件名相同,且這個類必須包含main()方法,main()的形式是固定的,以下:

public static void main(String[] args) {}

public關鍵字表此方法的權限,能夠被外界調用。

mian()方法的參數是一個String對象的數組。程序中並未使用args,args是用來存儲命令行參數。

1.編譯和運行

要編譯和運行Java程序,首先必需要有一個Java開發環境。

到Java官網下載對應平臺對應版本的JDK進行安裝,並配置環境變量。

在你存放HelloDate.java文件的目錄下打開命令行,輸入如下命令:

javac HelloDate.java

若是沒有任何提示信息,代表編譯經過,若是有報錯信息,根據錯誤信息進行問題解決。

而後再輸入如下命令運行程序:

java HelloDate

你就會看到程序輸出的消息和當天的日期。

八、註釋和嵌入式文檔

Java裏提供兩種註釋風格。

第一種風格,註釋以「/*」開始,隨後是註釋內容,並可跨越多行,最後以「*/」結束。

兩種表現形式:

/*
 * This is a comment
 * that continues
 * across lines
 */

/* This is a comment that
     continues across lines */

每行的開頭有沒有*號都是同樣的。

第二種風格,單行註釋,以「//」開頭,直到句末。

例如:

//This is a one-line comment

1.註釋文檔

javadoc是用於提取註釋的工具,它是JDK安裝的一部分。它採用了Java編譯器的某些技術,查找程序內的特殊註釋標籤。它不只解析有這些標籤呢標記的信息,也將毗鄰註釋的類名或方法名抽取出來。

javadoc輸出的是一個HTML文件,能夠用Web瀏覽器查看。

2.語法

全部的javadoc命令都只能在「/**」註釋中出現,註釋結束於「*/」。

使用javadoc命令的方式有兩種:嵌入HTML,或使用「文檔標籤」。

獨立文檔標籤是一些以「@」字符開頭的命令,且要置於註釋行的最前面。

共有三種類型的註釋文檔,分別對應於註釋位置後面的三種元素:類、域和方法。

例如:

/** A class comment */
public class Documentation1 {
    /** A field comment */
    public int i;
    /** A method comment */
    public void f() {}
}

javadoc只能爲public和protected成員進行文檔註釋。private和包內可訪問成員的註釋會被忽略掉。可使用-private進行標記,能夠將private成員的註釋也包括在內。

3.嵌入式HTML

javadoc經過生成的HTML文檔傳送HTML命令對代碼進行格式化。

例如:

//:object/Documentation2.java
/**
*<pre>
*System.out.println(new Date());
*/
///:~

也能夠自定義格式化,例如:

//:object/Documentation3.java
/**
 * You can <em>even</em> insert a list:
 * <ol>
 * <li> Item one
 * <li> Item two
 * <li> Item three
 * </ol>
 */
///:~

以上兩種形式就是嵌入式HTML。

嵌入式的HTML中不能使用標題標籤,例如:<h1>或者<hr>。

全部類型的註釋文檔都支持嵌入式HTML。

4.一些標籤示例

javadoc標籤詳細內容能夠參考JDK文檔。

1>@see:引用其餘類

@see標籤做用是引用其餘類的標籤,經過@see標籤能夠連接到其餘文檔。

例如:

/**
 * @see classname
 * @see fully-qualified-classname
 * @see fully-qualified-classname#method-name
 */

上述每種格式都會在生成的文檔中加入一個具備超連接的「See Also」條目。

javadoc不會檢查你所提供的超連接是否有效。

2>{@link package.class#member label}

該標籤與@see極其類似,只是它用於行內,而且用「label」做爲超連接文本。

/**
 * you can see {@link package.class#member label} about this class
 */

3>{@docRoot}

該標籤產生到文檔根目錄的相對路徑,用於文檔樹頁面的顯式超連接。

4>{@inheritDoc}

該標籤從當前這個類的最直接的基類中繼承相關文檔到當前的文檔註釋中。

5>@version

該標籤用於解釋代碼版本的相關信息。

格式以下:

@version version-information

使用javadoc -version命令,能夠直接提取出version-information。

6>@author

該標籤用於標識做者信息。可使用多個次標籤用於標識多個做者的信息,可是必須連續放置。

格式以下:

@author author-information
@author author-information

使用javadoc -author命令,能夠直接提取author-information。

7>@since

該標籤用於標識程序代碼的早期版本。

8>@param

該標籤用於方法文檔中,標識方法中的參數標識符,以及其釋義,可使用任意個數此標籤。

格式以下:

@param parameter-name description

9>@return

該標籤用於方法文檔,標識返回值的含義。

格式以下:

@return description

10>@throws

該標籤用於方法文檔,標識方法產生異常的相關信息。

格式以下:

@throws fully-qualified-class-name description

11>@deprecated

該標籤用於指出一些特性的改進。

在Java SE5中,此標籤已經被@Deprecated註解代替。

5.文檔示例

文檔註釋示例以下:

//:first/HelloDate.java
import java.util.Date;
/**
 *  The first Thinking in Java example program.
 *  Displays a string and today's date.
 * @author xjd
 * @author www.xxx.com.cn
 * @version 4.0
 */
public class HelloDate {
    /**
     *  Entry point to class & application
     * @param args array of string arguments
     * @throws exceptions No exceptions thrown
     */
    public static void main(String[] args) {
        System.out.println("Hello, it's: ");
        System.out.println(new Date());
    }/* Output:(55% match)
    Hello,it's:
    Thu Jun 28 17:56:45 CST 2018
    *///:~
}

第一行是做者獨特的方法,用一個「:」做爲特殊幾號說明這是包含原文件名的註釋行。

「///:~」標誌源代碼清單的結束。

/*Output標籤表示輸出的開始部分將由這個文件生成,經過這種形式,它會自動地測試以驗證其準確性。

(55% match)在向測試系統說明程序的當前運行和醒一次運行的輸出存在這很大差別,55%是兩次輸出與其的相關性程度。

九、編碼風格

Java編程語言編碼約定使用「駝峯風格」,駝峯風格規定:類名的首字母要大寫;若是類名由幾個單詞構成,那麼吧他們合併在一塊兒,其中每一個內部單詞首字母都採用大寫形式。方法、字段以及對象引用名稱等,將標識符的第一個單詞的首字母小寫,標識符內的其餘單詞首字母大寫。

例如:

class AllTheColorsOfTheRainbow{
    int anIntegerRepresentingColors;
    void changeTheHueOfTheColor(int newHue) {}
}

十、總結

經過本章的學習,你們已經接觸至關多的關於如何編寫一個簡單程序的Java編程知識,對Java語言及它的一些基本思想也有了一個整體認識。

我的總結:

本章大致介紹了Java的基礎知識,對面向對象編程也作了一些介紹。

上一篇:《Java編程思想》第一章:對象導論

下一篇:

相關文章
相關標籤/搜索