==========================
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é)果:
- 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)生長度為size
的int
數(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
強。
可看以下圖片,紅色為語法錯誤
六 、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~

如果,
將上述的`play()`方法,加上static關(guān)鍵字`public static void play()`,則結(jié)果是:

- 接口
>***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);