Java的哪些事
--------------------------------------------------
Java學習分2個方面: Java語法與Java類庫html
Java: A simple, object-oriented, network-savvy, interpeted, robust, secure, architecture-neutral, portable, high-performance, multithread, dynamic language.java
第一部分: Java語法
一. 字符集: Java使用Unicode字符集,採用UTF-16編碼.
Unicode 1.0的code point從U+0000到U+FFFF,只有一個code panel. 因爲編碼有餘,UTF-16對Unicode 1.0保留Surrogate Area(U+D800~U+DFFF), Surrogate Area不表示任何code point.
Unicode 2.0的code point從U+0000到U+10FFFF,分爲17個code panel,其中第0個code panel稱爲BMP(Basic multipline panel),涵蓋Unicode 1.0中的經典code point. 因爲編碼不足,UTF-16對Unicode 2.0中的Supplementary character採用巧妙的編碼方式: 將BMP的Surrogate area分紅high surrogate area(U+DC00~U+DFFF,共1024 bytes), low surrogate area(U+D800~U+DBFF,共1024 bytes), 各從high surrogate area與low surrogate area取4 bytes組成8 bytes的Surrogate pair共同表示一個Supplementary character,規定surrogate pair才能表示supplementatry character,單獨的high surrogate area或者單獨的low surrogate area都沒有意義.這樣,能夠表示(4*256)*(4*256)=16*65535個supplementary character,即16個code panel.
簡言之,在Unicode 2.0中UTF-16對Supplementary Character將BMP的字符編碼爲16位,將Supplementary Character編碼爲32位. 因此字符要用code point來表示,char只能表示BMP的字符.受此影響的API主要用String,StringBuffer與Character.
1.1 計算字符串的個數不能再用String.length():
int codeUnitLength=String.length();
int codePointCount=String.codePointCount(0,codeUnitLength);
1.2 遍歷字符串:
for(int i=0,n=String.length();i<n;i++){
int codePoint=String.codePointAt(i);
if(Character.isSupplementaryCodePoint(codePoint)){
i++;
}
//do something to codePoint.
}
1.3 Java中全有字符可用Unicode轉義序列替換.git
//2010年1月1日 星期五
JDK 1.5前使用Unicode1.0(U+0000~U+FFFF)字符集, 採用UTF-16編碼.
編碼方式: 每一個Code Point編碼16bit.
JDK 1.5後使用Unicode2.0(U+0000~U+10FFFF)字符集, 採用UTF-16編碼.
編碼方式: UTF-16將Unicode2.0分紅17個Code Panel, 其中第0字面涵蓋Unicode1.0, 稱爲Basic Multilingual Panel, BMP.其它16字面涵蓋全部Supplementle characters. UTF-16對BMP字符編碼不變,依然編碼16bit,但對Supplementle character採用巧妙的編碼形式, 它將BMP的Surrogate area(U+D800~U+DFFF,共2048bit)分紅Hign surrogate area(U+DC00~U+DFFF,共1024bit)與Low surrogate area(U+D800~U+DBFF,共1024bit),而後從Hight,Low Surrogate area各取4bit組成8bit的Surrogate pair,共同表示一個Supplementle character.這樣Supplementle character編碼32bit,其前16bit必須落入BMP Surrogate area, 很容易知道一個字符是否Supplementle character.
JDK 1.5後,字符不該該再用char表示,應該使用Code point表示程序員
//2010年8月7日: 簡結
字符是信息的基本載體.
字符集是字符的並集.
計算機只能表示0,1. 將字符轉換成01表示, 稱爲編碼.
編碼的基本概念:
code unit: 編碼的單位長度.
code point: 編碼的碼值.
code panel: 編碼的空間.
UTF-16編碼:
code unit是16 bytes
code point從U+0000到U+10FFFF
code panel共17個
其中第0 code panel包含全部classic unicode character, 稱爲BMP(Basic Multingual Panel).
其他16個code panel包含全部supplementary character.
UTF-16是一種變長(variable-length)編碼. 採用一種巧妙的方式處理supplementary character:
將BMP的surrogate area(從U+D800~U+DFFF,共2048 bytes)分紅low surrogate area(從U+D800~U+DBFF,共1024 bytes)和high surrogate area(從U+DC00~U+DFFF,共1024 bytes),而後各取8 bytes組成一個surrogate pair,做爲一個code unit.這樣能夠表示16*256*256=16*65536個supplementary character,即16個code panel.
因此, supplementary character碼長2個code unit, 必須注意!!!
--------------------------------------------------------------算法
二. 詞彙
2.1 保留字(keyword): Java有50個保留字,true與false是直接量(literal)
abstract continue for new switch
assert default goto package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while
注意:
Java的關鍵能夠分爲幾大類:
I. 類型定義
II.控制語句
III. 繼承封裝
IV. 異常捕獲
V. 成員修飾
VI. 命名空間
VII. 運算符
//2010年1月1日 星期五
Keywords are reserved words that have special meanings within the language syntax.sql
2.2 標識符(Identifier):
Java標識由字母,數字,下劃線(_),美圓符($)組成,而且不能以數字打頭,不能與保留字相同.
注意:
I.由於JVM編譯器解析的時候沒法區分數字直接量或數字打頭的標識符,因此標識不能由數字打頭.
II.由於Java使用Unicode字符集,其字母不限制於Lation單詞.因此標識符能夠是漢字,可用Character.isIdentifierStart()和Character.isIdentifierPart()檢測.
//2010年1月1日 星期五
Identifiers are names for constants, variables, functions, properties, methods and objects. The first character must be a letter, underscore or dollar sign. Following characters can also include digits. Letters are A to Z, a to z, and Unicode characters above hex 00C0. Java styling uses initial capital letter on object identifiers, uppercase for constant ids and lowercase for property, method and variable ids.
Note: an identifier must NOT be any word on the Java Reserved Word List.
2.3 直接量(Literal): 由解析器直接識別的文字.
//2010年8月6日
直接量(literal):
boolean直接量:
true,
false
char直接量:
'x',
轉義字符
interger直接量:
10進制:
8進制: 以0打頭
16進制: 以0x打頭
long型: 以L結尾
float直接量:
小數形式
10進制指數形式: 尾數,底數,指數都是10進制.
16進制指數形式: 尾數是16進制, 底數是2進制, 指數是10進制
float型: 以F結尾
Double型: 以D結尾
String直接量:
"..."
array直接量:
{...}
Object直接量:
nullexpress
注意:直接量(Literal)通常指基本類型而言.不一樣基本類型的直接量:
整型: 8進制以0打頭. 16進制以0x打頭. 長整型以L結尾.
浮點型: 小數形式, 指數形式: 尾數X(基)^指數, 基爲10用e表示(尾數是10進制,基是10,指數是10進制), 基爲16用p表示(尾數是16進制,基爲2,指數是10進制)
單精度以F結尾,雙精度以D結尾.
布爾型: true, false
字符型: 單引號括住的字符或者轉義序列(escape sequence).
Java的Escapse Sequence共10類:
\b: backspace
\f: formfeed
\n: newline
\r: carriage return
\t: horizontal tab
\\: backslash
\": double quote
\': single quote
\###: Octal encoded character
\uHHHH: Unicode encoded character
2.4 運算符(Operater):
參見<運算符與表達式>編程
2.5 空白符(White-char):
2.6 註釋(Comment):
注意: Java的註釋有3種, 單行(//), 多行(/*..*/), 文檔(/**..*/)設計模式
三. 數據類型,常量和變量
數據類型指數據的存儲表示.
Java存儲模型:
程序區
------
靜態區
------
堆
------
棧
其中,實例的對象建立在堆中,實例的引用建立在棧中.對象與引用是實例必不可少的二部分.api
1. 數據類型分類
Java數據類型分爲基本類型和引用類型.
基本類型包括: 布爾型,字符型,整型,浮點型
引用類型包括: 數據, 類, 接口, 枚舉, 註解
引用類型從多態角度又分爲編譯期類型與運行時類型.
引用類型從定義角度又分爲原生類型與泛生類型.
//2010年1月3日 星期日
基本類型:
(1)布爾型: boolean
直接量: true, false
Java的布爾型直接量爲true,false,而且不能參與數值運算;
C/C++的布爾型變量: 非0爲真,0爲假;真值爲1,假值爲0;能夠參與數值運算.
(2)字符型: char
直接量: 單括的字符或轉義字符
1)Java字符使用Unicode字符集,採用UTF-16編碼;C/C++的字符型變量點8位.
Java字符型和C/C++的字符型同樣,能夠參與數值運算.
(3)整型: byte,short,int long
直接量: 10進制,
8進制,
16進制,
long型
(4)浮點型: float,double
直接量: 10進制小數形式
10進制指數形式
16進制指數形式
單精度形式
雙精度形式
1)浮點型能夠除0, 結果是INFINITE或NAN, 因此浮點型的算術運算需用isInfinite(),isNaN()檢測結果可用性.
2)浮點型存在偏差, 因此浮點型的關係運算不許確.
-----------------------------------------------
引用類型:
(1)數組:
同構元素的有序集.
直接量: {...}
1)數組的getClassLoader()
基本類型的ClassLoader是bookstrap class loader,因此getClassLoader()返回null類型.
數組類型的ClassLoader是由Java Runtime動態建立的, 其getClassLoader()返回元素類型的ClassLoader.
因此不能使用Class.newInstance()動態建立數組, 需用Array.newInstance()動態建立.
2)聲明數組不容許指定維度,定義數組必須指定大小.
數組類型確切地說是一個指針,多維數組沒必要是齊整的.
3)數組的屬性:length, class.
4)數組的複製:
System.arraycopy(src,srcOffset,dest,destOffset,length);
Array.copyOf(src,length);
後者除了複製數組,還能夠擴充數組.例如:
int[] a=new int[10];
int[] b=Arrays.copyOf(a, a.length*2);
不管何者,複製都是淺拷貝.
5)多維數組: Java的N維數組能夠理解成一維數組的N-1維向量. 例如:
int[] a=new int[3];
int[][] aa=new int[3][];
int[][][] aaa=new int[3][][];
除第一維度必須在初化時指定. 其它維度能夠對應元素初始化時再指定. 由於Java的數組更相似於一個指針, 而不要求對稱!
(2)類: class
1)Object是全部類的基類.
(3)接口: interface
(4)枚舉: enum
枚舉與類類似,區別4點:
1)實例定義先於枚舉定義, 實例之間用逗號","隔開, 實例定義與枚舉定義之間用分號";"隔開.
2)枚舉能夠定義構造器與方法.
(2.1)構造器只能在定義內使用,定義外沒法訪問(因此無所謂private,public);
(2.2)預約義方法: Enum.values(), Enum.valueOf(), name(), ordinal(), getDeclareClass().
3)枚舉能夠用於switch-case-default.
4)枚舉不能是Local
public void method(){
enum E{...};//compile error, Enum cannot be local
}
(5)註解: @interface
註解與接口相似, 其語法爲:
@Target(PACKAGE|TYPE|FIELD|CONSTRUCTOR|METHOD|PARAMETER|LOCAL_VARIABLE|ANNOTATION_TYPE) 目標類型
@Retention(SOURCE|CLASS|RUNTIME) 保留策略
@Inherited 繼承性
@Documented 文檔化
modifiers @interface AnnotationName
{
type elementName();
或
type elementName default value;
}
1)註解只有元素的概念,沒有域與方法的概念
2)註解的類型:
基本類型
String
Class
enum
註解
以上類型的數組
3)註解是源碼的信息標籤. 處理器讀取這些信息並做相應處理. 不然註解沒有用地.
2. 類型轉換
(1)定義:將一種類型轉換爲另外一種類型.
(2)分類:類型轉換分自動轉換與強制轉換.
自動轉換隻發生在兼容的基本類型,不會丟失精度. 因此是安全的!!!
byte-->short-->int-->long-->double<--float
char-->int
強制轉換隻發生在同一類鏈, 其中向上強制轉換是安全的,向下強制轉換是危險的,需用instanceof或Class.isInstance()先做斷定.
(1)定義: 一種類型轉換爲別一種類型
(2)分類: 自動轉換,強制轉換
(3)原則: 類型轉換隻發生在兼容的數值類型之間或繼承鏈的類類型之間.
數值類型的低類型轉換爲高類型不會損失精度,是安全的,JVM自動轉換. 例如:表達式求值會把左右操做數自動轉換爲高類型後再計算.
數值類型的高類型轉換爲低類型會損失精度,是不安全的,必須強制轉換.
數值類型之間的合法轉換:
byte->short->int->long
int->double<-float
char ->int
類類型的子類型轉換爲基類型是向上類型轉換,或類型窄化.
類類開的基類型轉換爲子類型是向下類型轉換.
向上類型轉換是安全的, 例如基類類型能夠引用子類實例,從而實現多態性.
向下類型轉換是不安全的,必須先instanceof類型檢測,再強制轉換.
注意: C++中的布爾類型屬於數值類型,但Java的布爾類型區別數值類型, 不能進行類型轉換.
3.常量,變量及其特性
常量指值不變的量.
變量指值會變的量.
變量,常量具備4個基本要素: 存儲類別, 數據類型, 做用域與生存期.
Java不容許自定義存儲類別. 做用域爲聲明點到內層塊}結束處. 生存期分爲3種: 類, 實例, 局部.
變量的屏敝原則:
做用域或生存期相同的變量不能同名.
引伸: 局部變量能夠屏敝實例變量或類變量,但不能屏敝其它局部變量.
解釋: static int a;
{
int a;//一個是類變量,一個是實例變量,而且兩者定義塊{}不一樣, 不一樣生存期,且不一樣做用域, 因此能夠屏敝.
//2010年1月1日 星期五
此時a已是局部變量,以前解釋是錯誤的.
}
//2010年1月1日: 變量的生存期與初始化.
類變量與實例變量會自動初始化爲類型的"零值".
局部變量不會自動初始化,引用前必須手工初始化,不然編譯錯誤.
C/C++存在靜態存儲區的變量會自動初始化爲類型的默認值,但auto變量須要顯式初始化,不然引用不安全.
//2010年8月6日: Java與C++變量的比較
Java變量的生存期由其變量類型決定: 類變量,實例變量,局部變量;做用域也由類型變量決定.
C/C++變量的生存期由存儲類別決定,做用域由聲明位置決定.
Java的局變量引用前必須初始化,不然編譯出錯,而且局部變量不容許被屏敝.
C/C++的局部變量初始化前能夠直接引用,但不安全,並且也容許被屏敝.
四. 運算符和表達式
1.運算符要素: 優先級,結合性,直接影響表達式結果.
2.經常使用運算分類:
從功能角度:
算術運算符: + - * / % ++ --
關係運算符: > < >= <= != ==
邏輯運算符: ! && ||
位運算符: ~ & | ^ <<(算術左移) >>(算術右移) >>>(邏輯右移)
賦值或複合賦值運算符: = += -= *= /= %= ~= &= |= ^= <<= >>= >>>=(只與算術與位運算符結合)
字符串鏈接: +
"+"是Java語言重載的字符鏈接運算符.當其有一個操做數爲字串類型時生效.
Java不容許程序員重載運算符,這與C++不一樣.
實質上, Java提供StringBuffer(Thread-safe), StringBuilder的append()方法代替+操做,效率更好!
其它運算符: [] . ()
new
instanceof
?:
從操做數目角度:
一目運算符
二目運算符
三目運算符
3.運算符優先級及結合性
運算符 結合性
---------------------------------------------------------- ------------
[] . (方法調用)
! ~ ++ -- + - (強制轉換) new
* / %
+ -
<< >> >>>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /= %= &= |= ^= <<= >>= >>>=
4.運算符注意事項
(1) ()改變運算符優先級
(2) 不要使用生僻表達. 例如:
int a=10;
a=a++==0?++a:a--;
System.out.println(a);
//2010年1月3日 星期日
浮點型的算術運算與關係運算必須注意:
(1)浮點型能夠除0, 算術運算結果多是INFINITE(除0)或NAN(出錯),需用isInfinite()與isNaN()檢查結果可用性.
double a=1D/0;
System.out.println(a);
//結果是Infinite;
(2)浮點型存在偏差, 關係運算結果未必準確,"天生不可靠"!
(3)嚴格浮點數運算與strictfp關鍵字:
嚴格浮點數運算: 計算過程嚴格遵循IEEE 754標準,即計算結果是可預料的.
Java使用strictfp關鍵字表示嚴格浮點運算,
strictfp可修飾類,接口,具體方法,可是不能修飾抽象方法,例如:
abstract class A{
abstract strictfp int a();
}
不然編譯錯誤.
3. 對於要求精確結果的表達而方,不適宜使用double, float, long等類型,應該使用BigDecimal或BigInteger,或者直接使用int類型取替.
五. 語句
表達式語句
由表達式後加;造成表達式語句.
控制語句
順序
選擇
1. 雙分支:
if...else...有3種形式:
1.1 if(condition) statement;
1.2 if(condition)
statement;
else
statement;
1.3 if(condition1)
statement1;
else if(condition2)
statement2;
...
else if(conditionN)
statementN;
else
statementN+1;
2. 多分支:
switch(integer-expression){
case integer-constant1:
statement1; break;
...
case integer-constantN:
statementN; break;
default:
statementN+1;
}
注意: 多分支語句
(1)switch子句必須是整型表達式;
(2)case子句必須是整型常量表達式;
(3)case子句若是沒有break結束,將繼續往下執行;
JDK5.0後:
switch子句能夠是enum表達式;
case子句能夠是enum實例.
其中,switch子句的enum表達式中enum實例要用類型名引用,但case子句的enum實例卻不用類型名引用. 至關奇怪!!!
循環
1. for循環
for(initialization;condition;increment){
statement;
}
2. while循環
while(condition){
statement;
}
3. do-while循環
do{
statement;
}while(condition);
JDK1.5後:
foreach循環: 用於遍歷數組與Iterable對象.
for(ElemType elem:arrayOrIterable){
statement;
}
中斷
1. return函數返回.
2. throw異常拋出.
3. break, continue迭代結束.
3. break label, continue label帶標籤迭代結束.
注意:
1.break使流程跳轉到整個迭代結束處.
continue使流程跳轉到當次迭代結束處.
2.break的label能夠標記任意語句塊.
continue的label只能標記循環語句塊.
3.帶標籤的break能夠實現goto的效果.
4.在try-catch-finally中,不建議在finally中使用任何跳轉語句.由於它會覆蓋前面return或throw的結果.
注意: 控制語句的條件表達式涉及浮點型時務必謹慎:
(1)浮點型的算術運算必須注意特殊值INFINITIVE, NAN.
(2)浮點型的關係運算必須注意偏差, "天生不許確"!
複合語句{}
空語句;
異常處理try-catch-finally
斷言語句assert
assert Expression1 ;
assert Expression1 : Expression2 ;
//2010年8月6日
JDK 1.4需用
-enableassertions 或 -ea 選項啓用斷言
-disableassertions 或 -da 選項禁用斷言
六. 類
6.1 類相關的概念:
(1)程序設計原則:
自頂向下
逐步細化
模塊化設計
結構化編碼
(2)程序設計方法: POP,FOP,OOP,AOP及SOA
POP: Procedure-Oriented Programme, 面向過程編程.
FOP: Function-Oriented Programme, 面向函數編程.
OOP: Object-Oriented Programme, 面向對象編程.
AOP: Aspect-Orinted Programme, 面向切面編程.
SOA: Service-Oriented Programme, 面向服務編程.
POP, FOP, OOP, AOP, SOA串串燒:
程序=算法+數據結構;
SOP先設計問題的算法,再設計與之對應的數據結構.適合小代碼量的編程.
OOP先設計系統的數據結構,再設計與之對應的算法.適合大代碼量的編程.
POP與OOP的區別: 先有雞,先有蛋.
AOP輔助鬆耦合的擴展
SOA輔助鬆耦合的集成
OOP的四大特性: 抽象(Abstraction),封裝(Encapsulation),繼承(Inheritance),多態(Polymorphism)
軟件的不變真理就是變化.
抽象固化與變化部分.
封裝固化與變化部分.
繼承固化部分.
改寫變化部分.
OOP的缺陷: 面向對象的應用程序很大部分時間耗費在對象的建立與銷燬,合理複用對象會有效地提高性能.
(3)類和實例
類是抽象定義
實例是具體實現.
類是"模子"實例是"餅".
(4)引用和對象
實例的要素: 引用與對象, 兩者是實例不可分割的部分.
在Java的內存模型中,實例的對象建立在堆中,實例的引用建立在棧中.實例經過引用操做對象.
Java的內存模型直接決定:
(1)參數的傳遞: Java的參數傳遞都是"值傳遞",即將實參的棧值複製給形參.
對於基本類型而言,實參的棧值是真正的值.
對於引用類型而言,實參的棧值是實例的引用.
(2)變量的屏敝規則
生命期或做用域相同的變量不能被屏敝.
類變量或實例變量不能相互被屏敝,由於做用域相同.
類變量或實例變量能夠被局部變量屏敝,由於生存期與做用域都不一樣.
局部變量不能被局部變量屏敝,由於生存期相同.
注意形參也是局部變量.
(3)變量的初始化規則
類變量與實例變量自動初始爲類型的默認值.
局部變量不會自動初始化.
(4)線程的通訊與同步
子線程爲了提升性能,會在本線程保存主線程內存臨時拷貝. 除非使用volatile修飾,或使用synchronized同步.
(5)基類,子類,類繼承鏈或類鏈
(6)類之間的關係
常見的關係:
聚合(has-a)
依賴(use-a)
繼承(is-a)
------------------------------
UML明肯定義類的關係:
關聯(Association):
聚合(Aggregation):
依賴(Dependency):
泛化(Generalization):
-------------------------------------------
其中,
(1)關聯,聚合都是"has-a"關係,兩者區別微妙:
關聯的"has-a"是必不可少的組成部分.
聚合的"has-a"未必不可少的組成部分.
例如: 對於一我的,
胳膊腿腳必不可少,是關聯.
衣褲鞋襪不是必不可少,是聚合.
(2)依賴是"use-a"關係,是一種參照關係.
(3)泛化是"is-a"關係,即所謂的繼承(Inheritance).
6.2 類原語
(1)類定義
類訪問控制: public, package-private
抽象類: abstract
類拓展: extends
接口實現: implements
其它類修改符 : final, strictfp...
(3)接口定義
(4)枚舉定義
(5)Annotation定義
6.3 類的成員:
域, 描述類的狀態
方法, 描述類的行爲
//2010年1月4日 星期一
將非多態成員聲明爲final特性(private,static,final),讓編譯器內聯優化字節碼.
//2010年8月6日: 域初始化
(1)聲明時直接初始化
(2)初始化塊: {}
(3)構造器
若是是類成員:
(1)聲明時直接初始化
(2)靜態初始化塊: static{}
(3)按須要初始化容器類: Initialize-on-demand holder class(一種設計模式,在Effective Java 166頁)
//2010年8月6日: 方法原型(Signature)
方法原型(Signature): 方法名(方法參數類型列表)
//2010年8月6日: 方法參數傳遞
Java中只有一種參數傳遞方式: 值傳遞, 即將實參的棧值複製給形參數.
若是實參是基本類型,哪麼複製的內容即實參的值.
若是實參是引用類型,哪麼複製的內容即實參的引用.
注意final對象修改後會返回新對象.這也是String等看起來像"值傳遞"的緣由.
Java不能指定參數傳遞方式.
C/C++能夠指定參數傳遞方式:值傳遞,*指針傳遞或&引用傳遞. 至關靈活, 至關強悍!!!
//2010年8月6日: 方法重載與改寫,見下面的Overload與Override
6.4 Override和Overload
1.改寫必須相同方法原型(Signature,方法名與方法形參類型列表)
重載要求方法名相同便可.
2.改寫只在類繼承鏈的不一樣環節發生, 重載能夠類繼承鏈的不一樣環節或相同環節發生.
3.改寫必須注意三點:
3.1 改寫方法的返回類型或參數類型必須與被改寫方法的返回類型或參數類型相同或兼容,後者在JDK5.0稱爲類型協變.
3.2 改寫方法的訪問控制必須等於或高於被改寫方法的訪問控制.
3.3 改寫方法的被檢查異常必須是被改寫方法的被檢查異常或其子類.
重載必須注意三點:
重載方法的參數類型應該不兼容,不然容易引發歧義.
重載方法的參數列表與可變參數列表必須謹慎.
重載方法在反射機制裏是個難處理的角色,正如final特性在反序列化機制中是個難纏的角色.
6.5 構造器和finalize()方法
1.Java對象初始化工做的執行次序:
1)屬性的初始化.
2)初始化塊.
3)構造器.
4)若是有超類,先執行超類的1)~3).
5)若是屬性是對象,先執行屬性對象的1)~3).
2.構造器在實例建立時自動調用,通常用來初始化屬性.
3.構造器的特色:
1)沒有返回值.
2)與類同名.
3)能夠重載.
4)若是類中沒定義構造器,編譯自動建立默認構造器,即無參構造器.若是類中已定義構造器,編譯器再也不建立默認構造器.
//2010年1月4日 星期一
Java語言級可以在內存建立對象的功能:
1. 構造器
2. Clonable接口的clone()方法.
3. 反序列化接口的readResolve()方法或readReplace()方法.
//2009年12月28日 星期一
構造器用於建立實例並初始化域,類實例化過程爲: 先基類,再屬性,而後構造器.
子類構造器能夠在第一條語句並且必須第一條語句指定超類構造器,默認是超類的無參構造器.
初始化塊在類實例化時初始化域,其執行順序早於構造器.
靜態初始化塊在類加載時初始化類域.
//2010年1月4日 星期一
finalize()在垃圾收集器回收對象時調用,能夠用來清理工做.雖然可用System.gc(), System.runFinalization()通知垃圾收集器,但對象具體回收時機不可保證,所以finalize()不能做爲關鍵資源的清理工做.另外, finalize()不像C++的析構函數, Java類對象的finalize()鏈不能自動啓用,必須在finalize()中使用try-finally確保基類finalize()調用,或者設立finalizer guardar.後者利用回收對象自己必定會先回收其屬性的特性.
//2010年1月4日 星期一
因爲Java的內存模型特色:
1.在堆中的存儲分配會自動初始化爲對應類型的默認值.
2.在棧中的存儲分配不會自動初始化.
6.6 super和this
super,this是實例的二個隱含引用,都有2個做用.
super引用基類對象,引用基類構造器(只在構造器中).
this引用實例對象,引用構造器(只在構造器中).
6.7 成員修飾符
static,final,abstract,strictfp,volatile,native,transient
6.8 抽象類和接口
1.從定義角度:接口是常量與抽象方法的集合, 接口的屬性默認public static final, 接口的方法默認public abstract.
抽象類由能夠定義變量與具體方法.
2.從繼承角度:接口支持多繼承,抽象類只能單繼承.
3.從設計角度:接口用於組合,能夠在類繼承鏈的任意環節引入.
抽象類用於繼承,只能在類繼承鏈的頂層環節引入.
6.9 封裝,訪問控制
類的訪問控制只有public與package-private.
類的成員訪問控制有private,package-private,protected,public.
特殊的方法成員:
Factory方法.
Self-use方法.
6.10 多態:
多態定義:實例根據運行時類型選擇方法. 多態只體如今實例方法, 或稱只有實例方法具備多態性.
多態相關:編譯時類型,運行時類型,動態聯編,靜態聯編.
多態不是改寫:子類能夠改寫基類的類域,類方法,實例域,實例方法(或稱屏敝). 但多態只體如今實例方法.
多態陷阱: 多態方法的互調. 解決措施: Self-use方法.
繼承與組合:
面向對象程序設計中重用代碼的手段.
阻止繼承: final類和方法, private構造器.
將不需多態行爲的方法聲明爲final, 能夠優化字節碼.
6.11 嵌套類: 定義在類裏面的類, 其全限定名爲<外圍類全限定名>$<嵌套類名>, 注意$在Linux系統下必須轉義!
嵌套類(nested class)指在類內定義的類, 目的是服務外圍類.
嵌套類有四種:
靜態成員類(static member class),
實例成員類(instance member class),
局部類(local class)
匿名類(anonymous class)
其中後三者又統稱內部類(inner class)
靜態成員類等價正常類.
內部類能夠訪問實例閉包,結合接口能夠實現多繼承效果.
內部類也能夠繼承,實例化.但有一些特殊語法:
1. 繼承內部類,要在子類構造器初始化外圍實例.例如:
class A{
class InA{}
}
class B extends A.InA{
public B(A a){
a.super();//必須在第一條語句調用此句.
}
}
2. 建立內部類實例,要用<外圍實例>.new運算符,而不是new運算符.
3. 內部類訪問外圍實例, 使用<外圍類>.this引用,而不是this引用.
//2010年8月6日: 編碼習慣
使用this.引用實例變量
使用Klass.引用類變量
提升可讀性(一看就知道哪些是類變量,哪些是實例變量,哪些是局部變量).
4. 內部類訪問外圍變量或參數,必須聲明爲final特性,不然編譯錯誤.
七. Java體系
1. 物理概念及邏輯概念
類路徑: 類的根root. 通常使用-classpath選項或CLASSPATH環境變量指定.
類目錄: 類的目錄. 即文件系統的目錄.
類文件: 類的文件
命名空間
包
類
2. 概念串串燒
Java使用包的概念管理命名空間,
包類+類名=類的全限定名
包映射類目錄
類映射類文件
一個類文件能夠定義多個非public類, 可是隻能定義一個public類. 並且, public類必須與類文件同名.
main方法是Java應用程序的惟一入口,可是main方法能夠定義在非public類.
3. 包的定義與類的導入
類使用package語句定義包, package語句必須是類的起始語句.
類使用import語句導入包或類, import語句位於package語句後, 全部定義前.
4. 靜態導入import static
導入類或接口的可訪問static成員, 本地的static成員屏敝靜態導入的static成員.
八. JDK 5新語法
8.1 Generic type, 泛型
8.2 Foreach
8.3 Auto Boxing/Un-Boxing
根據上下文情景在基本類型及其包裝類型間自動轉換.
因爲Auto Boxing/Un-Boxing引發的一個歧義:
因爲Collection接口有remove(Object), List接口又有remove(int).
對於List對象而言,若是元素恰爲Integer類型,哪麼結合Auto-Boxing與un-boxing的時候,會調用哪一個重載方法?
List<Integer> intList = new ArrayList<Integer>();
intList.add(1);
// intList.add(2);
// intList.add(3);
System.out.println(intList);
intList.remove(1);
System.out.println(intList);
結果是:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
可見其準確調用remove(int),此時不會Auto Boxing/Un-boxing.
8.4 Variable parameter list
8.5 enum
枚舉是一種特殊的類:
1. 實例定義先於類定義, 實例間用comma隔開, 實例定義與類定義間用semicolon隔開.
2. 構造器只能在類定義內部調用,無所謂private與public.
3. 枚舉可用於switch-case-default,可是奇怪switch(Expression)中的實例常量要用枚舉類型名引用,但case(Expression)中的實例常量不用枚舉類型名引用.
4. 枚舉拓展Enum類,具備實例方法: ordinal(), name(), getDeclaringClass(),類方法values(),valueOf().
8.6 import static
8.7 annotation
第二部分: Java類庫
具體參照Java平臺技術體系.
系統包:13個一級包
java.lang
1.字符串處理:
CharSequence#
String: final實例
StringBuffer: 線程安全的mutable實例
StringBuilder: 線程兼容的mutable實例.
注意: String, StringBuffer, StringBuilder都提供Codepoint的支持,但只有String提供Regular Expression的支持.
2.反射機制:
(1)反射是利用類的運行時類型標識(Runtime Type Identity,RTTI)進行分析與編程的技術:
(2)反射API:
傳統API:
Interfaces:
Member
InvocationHandler
Classes:
Package
Class
AccessibleObject
Constructor
Method
Field
Array
Modifier
Proxy
ReflectPermission
針對GenericType:
GenericDeclaration: 範型定義,例如<K,E>, 只有Class, Counstructor, Method才實現(範型類,範型接口,範型方法)
Type
TypeVaraible: 類型變量, 例如 T.
ParameterizedType: 參數化類型, 例如 A<T>
GenericArrayType: 範型數組類型,例如 T[]或A<T>[]
WildchardType: 通配符類型, 例如 ?, ? extends T, ? super T.
另外在Class, Contructor, Method, Field中添加範型反射的方法.
具體參照<Java泛型.not>中的總結.
針對Annotation:
AnnotationElement
另外在Package, Class, Constructor, Method, Field中添加註解反射的方法.
3.代理:
(1)代理針對接口編程
(2)靜態代理中,代理對象與被代理對象實現相同接口,而後將被代理對象的請求轉發給代理對象處理, 即Decorator模式.
(3)動態代理的步驟:
(3.1)定義代理接口
(3.2)實現代理對象
(3.3)定義代理句柄(Invocation)
(3.4)建立(或綁定)被代理對象
使用Proxy.newInstance(ClassLoader, Class[], InvocationHandler)生成被代理對象.
參數一表示代理類加載器, null表示默認類加載器.
參數二表示代理接口
參數三表示代理句柄, 即(3.3)
等價於:
Class proxyClass=Proxy.getProxyClass(ClassLoader, Class[]).
proxyClass.getConstructor(new Class[]{InvocationHandler.class}).newInstance(invocationHandler);
習慣上,將(3.3),(3.4)由一個接口實現類完成.
代理陷阱: 調用循環
InvocationHandler{
Object invoke(Object proxy, Method method, Object[] args){
method.invoke(proxy,args);//形成死循環,無限地調用代理句柄.
}
}
java.math
java.util
1. 日期處理:
Date: final實例
Calendar: Date的輔助類
GregorianCalendar
DateFormat: Date的格式類
SimpleDateFormat
java.io
java.nio
1. nio使用的結構更接近於OS執行I/O的方式: Channel與Buffer.
2. Channel的類層次:
Closeable~
Channel#
ReadableByteChannel#
WriteableByteChannel#
ByteChannel: ReadablByteChannel與WriteableByteChannel的合併接口.
ScatteringByteChannel#
GatheringByteChannel#
InterruptibleChannel#
AbstractInterruptibleChannel
FileChannel: 實現ByteChannel, ScatteringByteChannel, GatheringByteChannel
SelectableChannel: 可經過 Selector 實現多路複用的通道。
ServerSocketChannel
SockeChannel: 實現ByteChannel, ScatteringByteChannel, GatheringByteChannel
DatagramChannel: 實現ByteChannel, ScatteringByteChannel, GatheringByteChannel
3. Buffer的類層次:
Buffer#
CharBuffer
ByteBuffer
MappedByteBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBufferr
4. Charset的類層次
Charset
CharsetDecoder
CharsetEncoder
CoderResult
CodingErrorAction
5. 應用:
(1)Channel分爲FileChannel與SelectableChannel.
FileChannel只能經過FileInputStream, FileOutputStream, RandomAccessFile獲取.
SelectableChannel可經過Selector實現多路利用, 主要包含ServerSocketChannel, SocketChannel, DatagramChannel.
(2)Channel交互對象是字節流. 若是交互對象是字符流, 需用Charset, CharsetEncoder, CharsetDecoder輔助.
(3)視圖緩衝器, 映射字節緩衝器
藉助ByteBuffer.asXXXBuffer()能夠建立其它類型緩衝器的視圖.
MappedByteBuffer
java.applet
java.awt
java.beans
java.net
java.rmi
java.security
java.sql
java.text
擴展包:21個一級包
javax.accessibility
javax.activation
javax.activity
javax.annotation
javax.crypto
javax.imageio
javax.jws
javax.lang.model
javax.management
javax.naming
javax.net
javax.print
javax.rmi
javax.script
javax.security.auth
javax.sound.midi
javax.sql
javax.swing
1. Applet是嵌入網頁運行的圖形化程序.
Applet的生命週期:
init()-->start()-->stop()-->destroy(), 在start()與stop()之間屢次調用pait(), repaint(), update()重畫界面.
2. Java圖形化程序設計要點:
(1)圖形化應用程序必須運行於EventQueue. 由EventQueue的DispatcherThread同步全部AWTEvent.
(2)圖形化應用程序必須調用System.exit(0)結束. 圖形化應用程序後臺每每多線程, 光是結束main線程是不夠的.
3. 參照<JFC Swing.not>
javax.tools
javax.transaction
javax.xml
第三方:14個一級包
org.ietf.jgss
org.omg.CORBA
org.omg.CORBA_2_3
org.omg.CosNaming
org.omg.Dynamic
org.omg.DynamicAny
org.omg.IOP
org.omg.Messaging
org.omg.PortableInterceptor
org.omg.PortableServer
org.omg.SendingContext
org.omg.stub.java.rmi
org.w3c.dom
org.xml.sax
--------------------------------------------------
實質上根本不夠能力去歸納.
--------------------------------------------------
一. Lang and util
//2010年1月1日 星期五
字符串處理: String, StringBuffer, StringBuilder
1. String, 字串final對象, 不少應用程序的安全性基於String的final特性.
2. StringBuffer, String的可變輔助類, 線程安全.
3. StringBuilder, StringBuffer的非同步版本.
字符串關鍵API:
length()/codePointCount(start, end)
equals()
equalsIgnoreCase()
charAt(position)/codePointAt(position)
//2010年1月4日 星期一
Date, Calendar, GregorianCalendar,
Date是final對象.
Calendar是Date可變輔助類.
GregorianCalendar是Calendar的具體子類.
這幾個類能夠完成涉及時間的大部分功能.
DateFormat, SimpleDateFormat是Date的格式類.
//2010年1月4日 星期一
Java中全部類都是Object的子類, Object自己具備若干關鍵方法,直接影響Java中其它類設計:
1.對象回收:
protected void finalize();
對象克隆:
protected Object clone() throws CloneNotSupportedException;
2.對象比較:
public boolean equals(Object obj);
public int hashCode();
3.對象格式:
public String toString();
4.線程同步:
public void wait();
public void wait(long);
public void notify();
public void notifyAll();
5.反射機制:
public Class<?> getClass();
//2010年1月4日 星期一
<Effective Java>關於equals(), hashCode()的算法:
equals必須知足:
自反性: x.equals(x)
對稱性: x.equals(y) --> y.equals(x)
傳遞性: x.equals(u) && y.equals(x) --> x.equals(z)
一致性: x,y未變--> x.equals(y)
非空引用: x.equals(null) --> false
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(!(obj instanceof TYPE)){ //或者:obj.getClass()!= this.getClass()
return false;
}
Type that=(Type)obj;
return (that.Y==Y)||(Y!=null && Y.equals(that.Y))...
//關鍵屬性的比較,注意對象爲空的狀況.
}
hashCode()必須知足:
相等對象的hashCode相等,不等對象的hashCode不等.
對於關鍵屬性x:
int result=17;//初始爲素數.
result=37*result+hashCode(x);
若是x是byte, short, char,強制轉爲int.
若是x是long, (int)(x^(x>>>32));
若是x是float, Float.floatToIntBits(x);
若是x是double, f=Double.doubleToLongBits(x);
f^(f>>>32);
若是x是boolean, x?0:1;
若是x是對象: x==null?-1:x.hashCode();
//2010年1月5日 星期二
一些關鍵的接口:
1. Cloneable標記接口,Object要使用clone方法,必須實例此接口,不然拋CloneNotSupportedException.
2. Comparable接口,在Collection frame的集合元素都應該實現此接口,若是沒有,須要在相應方法傳遞Comparator.
3. Iterable,使用要使用Foreach語法的對象,此接口返回Iterator對象.
4. Serializable,序列化機制必須的接口,其子類Externalizable提供可定製方法readExternal()與writeExternal().
//2010年1月5日 星期二
關於對象克隆: 除了使用Cloneable接口外,還可使用Java序列化機制,先將對象序列化,而後再反序列化獲得與原來對象同樣的內存存儲對象.但這種方式性能較低.
二. Collections
關於Java的Collections frame框架:
Collections frame的類圖:
Collection:
Set
HashSet
LinkedHashSet
TreeSet
List
ArrayList
LinkedList: Queue與Stack基本都用LinkedList實現.
Vector
Queue
Map:
HashMap
LinkedHashMap
TreeMap
輔助類或接口:
Collections
Arrays
關聯類或接口:
Iterator與Iterable
Comparator與Comparable
關聯方法:
equals()斷定是否相等調用.
hashCode()在哈希操做中用做Key.
注意:
1. Map接口不繼承Collection接口.
2. Vector是ArrayList的線程同步版本.
Hashtable是HashMap的線程同步版本.
3. Collections或Arrays包含大量集合操做的實用方法.
//2010年1月3日 星期日
Effective中關於equals,hashCode的算法,參考Effective Java
三. io/nio
1. Console類,表示從控制檯輸入,但不回顯.
2. JDK5.0提供Scanner掃描輸入.
3. JDK5.0提供Formater格式輸出.
Formatter與Formatable結合使用.
格式說明符語法:
%[格式][寬度.精度][t]轉換符
格式符6類9種:
符號: +(
填充: 空格0
左對齊: -
千位符: ,
進制符: #
參數索引: < $
轉換符:
10進制: d
16進制: x
8進制: o
小數形式: f
10進制指針形式: e
16進制指針形式: a
通用浮點數形式: g
字串: s
字符: c
布爾: b
散列碼: h
日期時間: tx
百分號: %
換行符: n
日期時間:
具體查看Formatter的API幫助.
4. Java2簡明教程:
4.1 流的層次結構:
java.io包的關鍵類: InputStream, OutputStream, File, RandomAccessFile, FileDescriptor
java.io包的異常類: IOException, FileNotFoundException, EOFException, InterruptedException.
InputStream:
1. StringBufferInputStream
2. ByteArrayInputStream
3. FileInputStream
4. FilterInputStream
4.1 BufferedInputStream
4.2 PushbackInputStream
4.3 LineNumberInputStream
4.4 DataInputStream
ObjectInputStream
5. PipedInputStream
6. SequenceInputStream
OutputStream:
1. ByteArrayOutputStream
2. FileOutputStream
3. FilterOutputStream
3.1 BufferedOutputStream
3.2 PrintStream
3.3 DataOutputStream
ObjectOutputStream
4. PipedOutputStream
4.2 File類:
File類封裝文件抽象路徑, 文件抽象路徑(File Abstract Path)既能夠文件的絕對路徑,也能夠文件相對路徑(相對"user.dir"系統屬性). 能夠建立,刪除,修改或查詢文件屬性,但不能讀寫文件內容.
文件相關操做步驟:
1. 先用File抽象文件.
2. 再做文件屬性相關的操做, 例如查詢文件是否存在,文件的建立時間之類.
3. 最後傳遞File建立IO流, 對文件內容進行讀寫.
4.3 RandomAccessFile類:
RandomAccessFile類同時實現InputStream與OutputStream接口,能夠隨機讀寫文件內容.
4.4 對象序列化機制:
序列化機制先檢測對象是否Externalizable,
若是是,調用其writeExternal()與readExternal()進行序列化與反序列化.
若是不是, 再檢測對象是否Serializable,
若是是, 調用其writeObject()與readObject()進行序列化與反序列化.
若是不是, 拋出NotSerializableException.
序列化過程當中,Serializable接口的writeReplace(), readReplace()方法能夠替換序列化與反序列化的結果.如下控制序列化過程的4個sercurity方法:
protected Object writeReplace() throws ObjectStreamException;
private void writeObject(ObjectOutputStream out) throws IOException;
private void readResolve(ObjectInputStream in) throws IOException, ClassNotFoundException;
protected Object readReplace() throws ObjectStreamException;
四. Net
五. thread and concurrent
六. JDBC
七. I18N
八. XML/JAXP
8.1 DOM
8.2 SAX
8.3 StAX
九. RegExp
十. Format
1. String.format/System.out.format(printf)
2. Formatter: 用於流的格式輸出, Formater(File/String)是替換, Formater(Appendable/OutputStream)是追加, 很奇怪的形式.
3. Scanner:用於流的掃描輸入,
十. Reflect/Tools
關於反射(Reflect)的總結:
<1> 反射是利用類的運行時類型標識(Runtime Type Identity, RTTI)進行分析與編程的技術.
<2> RTTI的關鍵API:
Class
Constructor
Method
Field
Array
其中,獲得Class的方式有3種:
Object.getClass()
Class.forName()
T.class類型常量, T能夠是primitive, 也能夠是reference, 包括數組類型.
JVM只爲每種類型維護一個Class對象,即Class是Singleton的.能夠直接使用==,!=進行比較.可是對於數組類型而言, ==是不兼容的, getName()也返回奇怪的名字, 須要用getCannonicalName()返回規範名字纔可讀.
另外,因爲array class loader是Java Runtime自動建立的, 其Class.getClassLoader()返回的是其元素的ClassLoader, 沒法使用Class.newInstance()來建立實例, 需用Array.newInstance(). Class.newInstance使用類的默認構造器建立實例,若是帶參構造器,須要使用先建立Constructor,而後由Construnctor.newInstance()來建立實例.
十一. Observe/Proxy
//2010年1月5日 星期二
1.Java代理面向接口編程,而不是面向具體類編程.
2.Java代理實現步驟:
2.1 定義代理接口和編寫代理實現類.
2.2 實現InvocationHandler接口,改寫invoke()方法添加代理邏輯.
2.3 建立被代理實例,建立方法有2種:
Proxy.newProxyInstance(ClassLoader proxyClassLoader,Class[] proxyInterfaceArray, InvocationHandler handler)
或者,
Class proxyClass=Proxy.getProxyClass(ClassLoader proxyClassLoader, Class[] proxyInterfaceArray);
ProxyType inst=proxyClass.getCounstructor(Class[]{InvocationHandler.class}).newInstance(new Object[]{invocationHandler});
後者須要拋出一串被檢查異常.
注意,不可在InvocationHandler.invoke(Object proxy, Method method, Object[] args)調用method.invoke(proxy,args),這樣將致使死循環,代理實例調用攔截,再調用代理實現...
3.Java代理不般用於隱藏後臺處理細節.經典實現:
/*
* 代理接口
*/
public interface ProxyInf {
void execute();
}
/*
* 代理實現
*/
public class ProxyImpl implements ProxyInf {
@Override
public void execute() {
System.out.println("ProxyImpl.execute()...");
}
}
/*
* InvocationHandler實現
*/
public class ProxyInvocationHandler implements InvocationHandler{
protected final ProxyInf proxyInst;
public ProxyInvocationHandler(ProxyInf proxyInst){
this.proxyInst=proxyInst;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(proxy.getClass().getName());
System.out.println(method.toString());
System.out.println(Arrays.toString(args));
return method.invoke(proxyInst, args);
}
}
/*
* 使用工廠方法建立代理實例
*/
public class ProxyFactory {
protected static ProxyInvocationHandler handler=new ProxyInvocationHandler(new ProxyImpl());
protected ProxyFactory(){}
public static ProxyInf newInstance() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// return (ProxyInf)Proxy.newProxyInstance(ProxyInf.class.getClassLoader(), new Class[]{ProxyInf.class}, handler);
Class<?> proxyClass=Proxy.getProxyClass(ProxyInf.class.getClassLoader(), new Class[]{ProxyInf.class});
ProxyInf proxyInst=(ProxyInf) proxyClass.getConstructor(new Class[]{InvocationHandler.class}).newInstance(new Object[]{handler});
return proxyInst;
}
}
十二. AWT/Swing/Applet/JavaBean
//2010年1月1日 星期五
Applet的理論總結:
1. Applet的執行環境: Applet嵌入瀏覽器的網頁中執行.
2. Applet的生命週期:
init, 初始化資源, 在網頁加載或網頁打開時調用.
start, 啓動處理, 在網頁獲取焦點時調用.
stop, 中止處理, 在網頁失去焦點時調用.
destroy, 銷燬資源, 在網頁關閉時調用.
另外,還有paint(),repaint(),update()方法供在各個生命週期切換中調用.
3. Applet的開發流程.
3.1 拓展Applet或JApplet,並改寫相應生命週期的回調方法.
3.2 藉助<applet>標籤嵌入html代碼,並設置codebase,code,width,height屬性.
//2010年1月1日 星期五
每一個Swing程序, 有兩點技術須要強調:
<1> 全部AWT/Swing組件必須由事件高度線程(Event Dispatch Thread)進行配置, 線程會將鼠標和鍵盤控制轉移到用戶接口組件.
不然會存在安全隱患,即便機率不多.
<2> 多個框架的程序中, 退出main方法, 只是終止主線程, 沒有終止程序. 事件調度線程保持程序處於激活狀態, 直到關閉全部框架或調用System.exit方法終止程序.
應該在退出程序時調用System.exit確保程序終止.
AWT/Swing的注意事項:
1. AWT/Swing應該在System EventQueue中執行.EventQueue的DispatchThread會同步處理AWTEvent.
System EventQueue能夠經過Tookit.getSystemEventQueue()獲取.
EventQueue.invokeXXX(Runnable)或
2. AWT/Swing結束時應該調用System.exit.因爲AWTEvent在System EventQueue的DispatchThread中處理, 僅僅結束main線程是不夠的.
JFrame.setDefaultOperation(JFrame.EXIT_ON_CLOSE)會在JFrame關閉時調用System.exit.
//2010年1月6日 星期三
AWT,Swing,SWT開發模式採用事件委託模型,
用戶經過鼠標,鍵盤操做組件-->組件產生事件-->事件傳達監聽器-->監聽器實現具體處理邏輯-->根據結果更新組件.
不一樣組件,不一樣事件,不一樣監聽器.而組件,事件,監聽器構成學習GUI的三個基本元素.
組件,佈局管理器,事件體系參見<JFC Swing.not>的總結.
學習AWT/Swing主要學習:
<1> 組件: 基本屬性及設置
高級模型及配置
<2> 佈局管理器: 效果及配置
<3> 事件: 類型及監聽器.
另外,Accelerator Key,
Key Stroke,
Image,
Graphics,
Color,
Rich Text,
Print
等功能,也是GUI必不可少.
//2010年1月6日 星期三
AWT/Swing類層次結構:
Object
Button
Canvas
CheckBox
Choice
Container
BasicSplitPanelDivider
CellRendererPane
DefaultTreeCellEditor.EditorContainer
JComponent //全部Swing組件的蕨類, 包括JPanel與JScrollPane
Panel
ScrollPane
Window
BasicToolBarUI.DragWindow
Dialog
JDialog
Frame
JFrame
JWindow
Label
List
Scrollbar
Text Component
TextArea
TextField
可見,AWT是Swing的基礎,另外,Swing繼續沿用AWTEvent以及LayoutManager,儘管也用LayoutManager2.
//2010年1月6日 星期三
1. JFrame
Swing對於heavyweight component的設計模型:
Window Applet
Frame Dialog
JFrame JDialog JWindow JApplet JInternalFrame
上面JFrame, JDialog, JWindow, JApplet, JInternalFrame都實現RootPaneContainer接口,其中前面者是heavyweight component,後者是lightweight component.
RootPaneContainer接口返回一個JRootPane,每一個JRootPane包含一個JContentPane, 一個JGlassPane, 一個MenuBar, 一個JLayeredPane.
JGlassPane位於頂層, 通常用於捕捉鼠標事件, 也可用於描繪頂層組件.
JLayeredPane包含6個經常使用的層:
DEFAULT_LAYER: 默認層, 位於Integer(0).
PALATTE_LAYER: 調色板層, 位於Integer(100).
MODEL_LAYER: 模型層, 位於Integer(200).
POPUP_LAYER: 彈出層, 位於Integer(300).
DRAG_LAYER: 拖拉層, 位於Integer(400).
FRAME_CONTENT_LAYER: 內容層, 位於Integer(-30000).
MenuBar位於內容層.
十三. RMI
十四. Security/JAAS
//2010年1月2日 星期六
1. ClassLoader, 參考API
簡結:
ClassLoader負責加載類字節碼,並建立Class對象.
Class對象包含定義其的ClassLoader引用.
數組類型的Class對象的ClassLoader其元素的ClassLoader對象,由Java Runtime自動建立.
基本類型的Class對象的ClassLoader爲null.
//2010年1月3日 星期日
When the JVM is started, three class loader is used:
1. Bookstrap class loader
2. Extensions class loader
3. System class loader
The bookstrap class loader loads the core java libraries, which locate at <JAVA_HOME>/lib directory.
The bookstrap class loader is part of the core JVM, which is written in native language, such as C/C++.
The bookstrap class loader has not ClassLoader object.
For example, String.class.getClassLoader() is null.
The extensions class loader loads the extensions libraries, which locate at <JAVA_HOME>/lib/ext or any other directory specified by "java.ext.dirs" system property.
The extensions class loader is implemented by "sun.misc.Launcher$ExtClassLoader" class.
The extensions class loader will not reference any other class path,即擴展類加載器不使用類路徑.
The system class loader loads the application libraries, which locate at directory specified by "CLASSPATH" system variable or "java.class.path" system property.
The system class loader is implemented by "sun.misc.Lanucher$AppClassLoader" class.
//2010年1月2日 星期六
ClassLoader的加載機制:
1. Class與ClassLoader加載資源時的區別:
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
由源碼可見,Class.getResource delegate to ClassLoader.getResource, if ClassLoader is a bookstrap class loader, it will delegate to ClassLoader.getSystemResource().
但與ClassLoader.getResource()不一樣,Class.getResource()先調用resolveName()對resource name進行解析. 因此, Class.getResource()能夠指定/打頭的絕對路徑,也能夠指定相對路徑,可是ClassLoader.getResource()只能指定相對CLASSPATH的路徑,即不能指定以/打頭的絕對路徑,不然返回null.
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
由源碼可見,ClassLoader會調用parent class loader的getResource()來查找資源,若是parent是bookstrap class loader,則別外處理.在parent class loader返回null的狀況下,再次調用findResource()來處理.注意,這裏的findResource()指的是沿着class loader chain從下往上依次調用getResource()來查找,而不是目錄結構的樹形查找.
十五. Native
十六. Annotation
--------------------------------------------------
隨筆
--------------------------------------------------
1. 類->Java變量的域初始化
Java的類變量,實例變量會自動初始化類型的默認值, 局部變量不會自動初始化, 引用前必須顯式初始化.
這個規則的惟一例外就是final域必須顯式初始化, 不管是類變量, 仍是實例變量.
顯式初始化類變量:
(1)聲明同時初始化
(2)static初始化塊
顯式初始化實例變量:
(1)聲明同時初始化
(2)初始化塊
(3)構造器
2. 類->this,super
this引用當前實例或重載構造器,若是引用重載構造器,必須位於某個構造器中.
super引用基類實例或基類構造器,若是引用基類構造器,必須位於子類構造器的首語句.
3. lang and util->Random
Random(long seed)相同隨機因子產生的隨機序列相同.若是不指定隨機因子或使用System.nanoTime()做爲隨機因子.
Random的nextInt(int)方法比較隨機.其使用的算法不一樣.
4. Java體系->垃圾回收與finalize()方法
JVM根據某種垃圾回收算法回收無用對象,釋放佔用內存.回收前調用對象的finalize()方法.
因爲回收時機不肯定,finalize()顯得不可靠,不能用於關鍵資源的回收.
垃圾回收相關方法:
System.gc()啓動垃圾回收.
System.runFinalization()執行回收對象的finalize()方法.
gc與runFinalization()的區別: 某個對象零引用後會自動標記爲回收對象, 但可能還在堆中. 由於還沒有啓動垃圾回收. 這種現象與垃圾回收算法相關.
5. lang and util->Runtime
6. Java體系->
(1)物理概念: 類路徑,類目錄,類文件.
(2)邏輯概念: 命名空間,包,類
(3)定義包: package語句
(4)導入包或類: import語句
(5)靜態導入: import static語句
(6)設置類路徑: -classpath選項或CLASSPATH環境變量
7. 類-> (1)類和實例 類是抽象定義,實例是具體實現 (2)基類,子類,繼承鏈 (3)類的關係: is-a: 泛化(Generalization,或繼承) has-a: 關聯(Association),聚合(Aggregation) 關聯是必不可少, 聚合是無關緊要. 或者, 關聯是一對一, 聚合是一對多(零或多) use-a: 依賴(Dependency) (4)動態綁定: 編譯時類型和運行時類型 (5)重載(Overload)和改寫(Override) (1)從定義角度: 重載指方法名相同,形參列表不一樣. 改寫指方法簽名必須相同. (2)從發生角度: 重載發生在繼承鏈的上下,或相同結點. 改寫發生在繼承鏈的上下環節. (3)從設計角度: 重載實現編譯時的多態, 即根據形參綁定不一樣方法. 改寫實現運行時的多態, 即根據運行時類型綁定不一樣方法. 注意事項: (1)重載方法的形參列表必須個數不一樣,或者類型不兼容. 不然容易產生歧義. (2)訪問控制: 改寫方法的訪問控制必須等於或高於被改寫方法的訪問控制. 參數類型: 改寫方法的返回類型與形參類型必須等於或兼容被改寫方法的返回類型與參數類型,兼容的狀況又稱爲類型協變. 被檢查異常: 改寫方法的被檢查異常必須等於或兼容被改寫方法的被檢查異常,兼容的狀況也可視做類型協變. (6)多態,改寫: 多態與改寫是徹底不一樣的概念, 子類能夠改寫基類的任何可訪問成員, 即替換. 但多態只體如今成實例方法, 即實例方法根據運行時類型綁定, 其它成員根據編譯時類型綁定. (7)final: final類不可被繼承 final方法不可被改寫 final域不可再賦值 注意事項: (1)final域必須顯式初始化. (2)final類或final方法能夠優化字節碼,使用內聯調用. (3)final實例,final引用,final對象的區別: final實例指引用與對象都不可變. final引用指引用不可變. final對象指對象不可變. (4)final對象實現: (1)全部可訪問域都是final實例, 理想狀態. (2)不提供域的Mutator方法. (3)對可變域的Accessor方法提供保護性拷貝.8. 數據類型->類型轉換 (1)類型轉換指一種類型轉換爲別一種類型. (2)類型轉換隻發生在兼容的數值類型或繼承鏈的類類型之間. 數據類型的低類型向高類型轉換不會損失精度,是安全的. 數據類型的高類型向低類型轉換會損失精度,是不安全的. 數值類型的合法轉換: char->int byte->short->int->long int->double<-float 類類型的子類向基類轉換叫向上類型轉換. 類類型的基類向子類轉換叫向下類型轉換. 向上類型轉換是安全的,向下類型類型是危險的,必須先instanceof類型檢測.9. 類->抽象類,接口 (1)從定義角度: 接口是常量與抽象方法的集合, 全部域默認public static final, 全部方法默認public abstract. 抽象類能夠定義變量與具體方法. (2)從繼承角度: 接口支持多繼承, 抽象類只支持單繼承. (3)從設計角度: 接口用於實現組合, 能夠在繼承鏈的任意環節引入, 但要維護實現接口的全部類. 抽象類用於實現繼承, 只能在繼承鏈的頂層環節引入, 但只須要維護基類便可.10. 類->訪問控制 (1)類的訪問控制: public, package-private (2)成員訪問控制: public, protected, package-private, private11. 類->Object: 全部類的基類.12. 類->equals(),hashCode()改寫 equals()必須知足: 自反,對稱,傳遞,一致. hashCode()必須知足: x.equals(y), x.hashCode()==y.hashCode(). 實現算法見<effective javae>