用引用操縱對象
盡管Java中一切都看作為對象泛啸,但是操縱的標識符實際上對象的一個“引用”。
String s; // 這里只是創(chuàng)建了一個引用勺届,而不是一個對象
String s = new String("abcd"); // 使用`new`操作符來創(chuàng)建一個對象,并將其與一個引用相關(guān)聯(lián)
String s = "abcd"; // 字符串可以直接用帶引號的文本初始化
必須由你創(chuàng)建所有對象
使用new
操作符創(chuàng)建一個對象
存儲到什么位置
由五個地方可以存儲數(shù)據(jù):
- 寄存器:由于寄存器數(shù)量有限派桩,所有無法直接控制
- 堆棧(棧):RAM中椭盏,存儲在棧中的數(shù)據(jù)必須明確知道其生命周期,通常局部存放對象引用和局部基本類型的變量峻呕。
- 堆:存放所有的對象
- 常量存儲:通常直接存放在代碼內(nèi)部吭敢,其永遠不會改變
- 非RAM存儲:數(shù)據(jù)存放在程序之外茎芭,不受程序的控制员魏,如流對象(System.out)和持久化對象(存放在磁盤的文件)乌叶。
特例:基本類型
一些比較小的,簡單的類型讯私,如果放在堆中往往效率不高热押,所以這些類型不需要使用new
來創(chuàng)建,而是創(chuàng)建一個“自動”變量來直接存儲“值”斤寇,并置于棧中桶癣。
Java 中所有基本類型所占據(jù)存儲空間的大小都是明確的.
- 所有數(shù)值類型都有正負號
-
boolean
類型所占存儲空間的大小沒有明確,僅定義為能夠去字面值true
或false
- 基本類型和其對應(yīng)的包裝類之間可以自動裝包娘锁、自動解包
- Java 提供了兩個用于高精度計算的類:
BigInteger
和BigDecimal
Java 中的數(shù)組
- Java 確保數(shù)組會被初始化牙寞,且會進行范圍檢查
- 當(dāng)創(chuàng)建一個數(shù)組對象時實際就是創(chuàng)建一個引用數(shù)組,并且每個引用都會被自動初始化為一個特定值
null
- 也可以創(chuàng)建用來存放基本數(shù)據(jù)類型的數(shù)組莫秆,此時的初始化則是置零
永遠不需要銷毀對象
作用域
- 作用域決定了在其內(nèi)定義的變量的可見性和生命周期
- 在作用域里定義的變量只可用于作用域結(jié)束前
- Java 中不允許“覆蓋”變量的可見性
{
int x = 12;
// x available
{
int q = 96;
// Both x & q available
int x = 96 // Illegal
}
// only x available
}
對象的作用域
- Java 對象不具備和基本類型一樣的生命周期碎税,由
new
創(chuàng)建的對象,只要你需要馏锡,其會一直保留下去。 - Java 使用垃圾回收器來監(jiān)視
new
創(chuàng)建的對象伟端,辨別并釋放那些不會再被引用的對象
創(chuàng)建新的數(shù)據(jù)類型:類
使用class
來創(chuàng)建一個新的類型:
class ATypeName { }
字段和方法
一旦定義了一個類杯道,就可以在類中設(shè)置兩種元素:字段(數(shù)據(jù)成員)和方法(成員函數(shù))。字段可以是任何類型的對象或基礎(chǔ)類型。每個對象都有存儲其字段的空間党巾,即普通字段不在對象間共享萎庭。
引用一個對象的成員的方式:objectReference.member
基本數(shù)據(jù)類型的變量只有是類的成員時,才確保其獲得一個默認值齿拂,否則的話驳规,與C++一樣,該變量可能是任意值(其實就是在堆還是棧的問題嘛)署海,不過這種情況下Java會報編譯錯誤吗购。
方法、參數(shù)和返回值
方法的基本組成部分包括:名稱砸狞、參數(shù)捻勉、返回值和方法體:
ReturnType methodName ( /* Argument list */) {
/* Method body */
}
方法名和參數(shù)列表唯一地標識某個方法(合起來稱為“方法簽名”)注意:方法簽名不包含返回值。
Java 中的方法只能作為類的一部分來創(chuàng)建刀森,方法通常只有通過對象才能調(diào)用踱启,且這個對象必須有這個方法。
參數(shù)列表
方法的參數(shù)列表指定要傳遞給方法什么樣的信息研底,這里采用的都是對象的類型埠偿,即包含指定的類型和名字,這里傳遞的實際上是引用榜晦,傳遞基礎(chǔ)類型則通過自動包裝來實現(xiàn)冠蒋。
構(gòu)建一個 Java 程序
名字可見性
為了防止不同類庫中使用了相同的類名,Java 將反過來的域名作為唯一標識符(即包名)芽隆,如我的域名為codeand.fun
,則我的類庫則使用fun.codeand.utils
的形式浊服。
包名使用小寫
運用其他構(gòu)件
使用import
導(dǎo)入想要的包:
import java.util.ArrayList;
import java.util.*; // 導(dǎo)入java.util下所有的類
java.lang
默認導(dǎo)入到每一個Java文件中。
static 關(guān)鍵字
當(dāng)聲明一個事物為static
時胚吁,就意味著這個域或方法不會與包含它的類的任何對象實例關(guān)聯(lián)在一起牙躺,可以理解為類數(shù)據(jù)和類方法。
class StaticTest {
static int i = 47;
static void inc() { i++; }
}
int j = StaticTest.i; // 47
StaticTest st1 = new StaticTest();
StaticTest.inc();
StaticTest st2 = new StaticTest();
// st1.i == st2.i == 48 // 所有i都指向同一個存儲空間
你的第一個 Java 程序
// HelloDate.java
import java.util.*;
public class HelloDate {
public static void main(String[] args) {
System.out.println("Hello, it's");
System.out.println(new Date());
}
}
要創(chuàng)建一個獨立運行的程序腕扶,那么該文件中必須存在某個類與該文件同名孽拷,且那個類必須又一個main
方法,其形式如public static void main(String[] args)
半抱。
編譯和運行
$ javac HelloDate.java // 編譯脓恕,產(chǎn)生一個 HelloDate.class 文件
$ java HelloDate // 運行
注釋和嵌入式文檔
- 多行注釋:
/* something */
- 單行注釋:
// something
注釋文檔
Java 中可以將代碼與文檔放到一個文件中,這樣有利于文檔的維護窿侈,為了實現(xiàn)這一目的炼幔,這里使用一種特殊的注釋語法來標記文檔,此外還有一個工具javadoc
來提取注釋史简。javadoc的輸出是一個html
# wuxiaobai24 @ wuxiaobai24-pc in ~/code/Java/ch2 [17:56:05] C:1
$ javadoc HelloDate.java
正在加載源文件HelloDate.java...
正在構(gòu)造 Javadoc 信息...
標準 Doclet 版本 1.8.0_242
正在構(gòu)建所有程序包和類的樹...
正在生成./HelloDate.html...
正在生成./package-frame.html...
正在生成./package-summary.html...
正在生成./package-tree.html...
正在生成./constant-values.html...
正在構(gòu)建所有程序包和類的索引...
正在生成./overview-tree.html...
正在生成./index-all.html...
正在生成./deprecated-list.html...
正在構(gòu)建所有類的索引...
正在生成./allclasses-frame.html...
正在生成./allclasses-noframe.html...
正在生成./index.html...
正在生成./help-doc.html...
# wuxiaobai24 @ wuxiaobai24-pc in ~/code/Java/ch2 [17:56:11]
$ ls
allclasses-frame.html HelloDate.class index-all.html package-list stylesheet.css
allclasses-noframe.html HelloDate.html index.html package-summary.html
constant-values.html HelloDate.java overview-tree.html package-tree.html
deprecated-list.html help-doc.html package-frame.html script.js
注釋語法
所有 javadoc 命令都只能在由/**
和*/
組成的注釋中
javadoc 的注釋乃秀,只能為public
和protected
成員進行文檔注釋,而private
和defaule
成員的注釋會被忽視掉
javadoc 主要有兩種形式:
- 嵌入HTML
-
文檔標簽:
-
獨立文檔標簽是一些以
@
字符開頭的命令,且置于注釋行的最前面(除了前導(dǎo)的*
) -
行內(nèi)文檔標簽則可以在 javadoc 注釋中的任何位置跺讯,同樣以
@
開頭枢贿,但要在花括號內(nèi)。
-
獨立文檔標簽是一些以
常用的標簽有:
-
@see
:引用其他類刀脏,會生成一個超鏈接條目(不會校驗該鏈接是否有效)局荚,超鏈接文本為“See Also”@see classname @see fully-qualified-classname @see fully-qualified-classname@method-name
-
{@link package.class#member label}
:與@see
類似,不過是行內(nèi)標簽愈污,使用“l(fā)abel”來處理作為超鏈接文本 -
{@docRoot}
:該標簽產(chǎn)生到文檔根目錄的相對路徑 -
{@inheritDoc}
:該標簽從當(dāng)前這個類最直接的基類繼承相關(guān)文檔到當(dāng)前文檔注釋中 -
@version
:版本信息 -
@author
:作者信息 -
@since
:指定JDK版本最低為多少 -
@param
:表示參數(shù)含義耀态,形式如@param parameter-name description
-
@return
:描述返回值,形式如@return description
-
@throws
:異常描述钙畔,該方法可能拋出的每個異常都需要說明茫陆,形式如@throws fully-qualified-class-name description
-
@deprecated
:指出一些舊特性已由改進的新特性所取代,不建議使用擎析。調(diào)用一個標記為@deprecated
的方法簿盅,編譯器會發(fā)出警告。
// HelloDate.java
import java.util.*;
/** A class comment
* Test comment
* @author wuxiaobai24
* @version 0.1
*/
public class HelloDate {
/** a field comment */
public int i;
/**
* a <strong>protected</strong> filed comment
* <ol>
* <li>one</li>
* <li>two</li>
* <li>three</li>
* </ol>
*/
protected int p;
/** a private field comment */
private int j;
/** A method comment
* @param args args comment
*/
public static void main(String[] args) {
System.out.println("Hello, it's");
System.out.println(new Date());
}
}
編碼風(fēng)格
- 駝峰式寫法
- 標識符的第一個字符采用小寫揍魂,其余用大寫
練習(xí)
練習(xí)1
// Ex1.java
public class Ex1 {
public int i;
public char c;
public static void main(String[] args) {
Ex1 e = new Ex1();
System.out.println(e.i);
System.out.println(e.c);
}
}
練習(xí)2
// Ex2.java
public class Ex2 {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
練習(xí)3 & 練習(xí)4 & 練習(xí)5
// Ex3.java
class DataOnly {
int i;
double d;
boolean b;
}
class ATypeName {
}
public class Ex3 {
public static void main(String[] args) {
ATypeName a = new ATypeName();
DataOnly d = new DataOnly();
d.i = 1;
d.d = 2.0;
d.b = false;
System.out.println(d.i);
System.out.println(d.d);
System.out.println(d.b);
}
}
練習(xí)6
// Ex4.java
public class Ex4 {
int storage(String s) {
return s.length() * 2;
}
public static void main(String[] args) {
String s = new String("Hello");
Ex4 e = new Ex4();
int len = e.storage(s);
System.out.println(len);
}
}
練習(xí)7 & 練習(xí)8
// Ex7.java
class StaticTest {
static int i = 47;
}
class Incrementable {
static void increment() { StaticTest.i++; }
}
public class Ex7 {
public static void main(String[] args) {
StaticTest st1 = new StaticTest();
Incrementable.increment();
StaticTest st2 = new StaticTest();
System.out.println(st1.i);
System.out.println(st2.i);
System.out.println(StaticTest.i);
}
}
練習(xí)9
// Ex9.java
public class Ex9 {
public static void main(String[] args) {
int i = 24;
Integer bi = i;
System.out.println(i);
System.out.println(bi);
// ....
}
}
練習(xí)10
// Ex10.java
public class Ex10 {
public static void main(String[] args) {
if (args.length == 3) {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
}
}
}
練習(xí)11
// Ex11.java
class AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors;
void changeTheHueOfTheColor(int newHue) {
anIntegerRepresentingColors = newHue;
}
}
public class Ex11 {
public static void main(String[] args) {
AllTheColorsOfTheRainbow allTheColorsOfTheRainbow = new AllTheColorsOfTheRainbow();
allTheColorsOfTheRainbow.changeTheHueOfTheColor(1);
System.out.println(allTheColorsOfTheRainbow.anIntegerRepresentingColors);
}
}
本文首發(fā)于Code & Fun