2011年10月24日 星期一
[MEMO] JAVA 實作 this
public class test111024 {
public static void main (String args[])
{
Car car = new Car(4,"Benz");
car.printData();
}
}
class Car{
protected int wheel;
protected String name;
public Car(int wheel,String name)
{
this.name = name;
this.wheel = wheel;
}
public void printData()
{
System.out.println("The car has: " + wheel + " wheels.");
System.out.println();
System.out.println("The car's name is: " + name + ".");
}
}
2011年10月20日 星期四
[MEMO] JAVA 實作
剛剛參考別人網誌對於Hashtable的使用...遇到了幾個提示
原址:http://blog.yam.com/bluelanguage/article/8401664
以下是人家的 code 經過我重新修正後:
package hoge;
import java.util.*;
import java.io.*;
class Student {
private String number;
private String name;
private double score;
public Student(String number, String name, double score) {
this.number = number;
this.name = name;
this.score = score;
}
public String getNumber() {
return number;
}
public String getName() {
return name;
}
public double getScore() {
return score;
}
}
public class Convert2 {
public static void main(String[] args) {
try {
OpHashtable();
}
catch(IOException e) {
System.out.println(e.toString());
}
}
private static void OpHashtable() throws IOException {
Hashtable table = new Hashtable();
BufferedReader buf = new BufferedReader(
new InputStreamReader(System.in));
int select;
String number, name;
double score;
Object val;
Student student;
System.out.println("使用Hashtable類別");
while(true) {
System.out.println("(1) 加入學生資料");
System.out.println("(2) 查詢學生資料");
System.out.println("(3) 移除學生資料");
System.out.println("(4) 列出所有資料");
System.out.println("(5) 離開");
System.out.print("> ");
select = Integer.parseInt(buf.readLine());
switch(select) {
case 1:
System.out.print("學號: ");
number = buf.readLine();
System.out.print("姓名: ");
name = buf.readLine();
System.out.print("成績: ");
score = Double.parseDouble(buf.readLine());
student = new Student(number, name, score);
val = table.put(number, student);
if(val == null){
System.out.println("資料存入....");}
else{
System.out.println("資料取代....");
break;}
case 2:
System.out.print("學號: ");
number = buf.readLine();
student = (Student) table.get(number);
if(student != null)
{System.out.println("學號: " + student.getNumber() +
" 姓名: " + student.getName() +
" 成績: " + student.getScore());}
else
{System.out.println("查無此筆資料....");
break;}
case 3:
System.out.print("學號: ");
number = buf.readLine();
val = table.remove(number);
if(val != null)
{System.out.println("學生 " + number + " 資料移除");}
else
{System.out.println("查無此筆資料....");
break;}
case 4:
{Enumeration e = table.elements();
while(e.hasMoreElements()) {
student = (Student) e.nextElement();
System.out.println("學號: " + student.getNumber() +
" 姓名: " + student.getName() +
" 成績: " + student.getScore());
}
break;}
case 5:
{efault:System.exit(0);}
}
}
}
}
在Hashtable的地方看到了一個提示
「 **** is a raw type. References to generic type ***** should be parameterized. 」
拿去Google後有人建議先去看泛型的 document......, 索性整理了一下。
http://www.javaworld.com.tw/jute/post/view?bid=5&id=105545&sty=3&tpg=1&age=0
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
2011年10月18日 星期二
[MEMO] JAVA 實作
取自 JAVA由初學邁向認證
範例 Chap5 DefineClass2
public class DefineClass2 {
public static void main(String[] args){
Vehicle newCar1 = new Vehicle(); //實體化一個物件
Vehicle newCar2 = new Vehicle(); //再實體化另一個物件
Vehicle rCar; //只是一個參考
rCar = newCar1; //rCar指向newCar1
newCar1.wheel = 4; //指定實體變數的值
newCar2.wheel = 8;
rCar.wheel = 6; //現在,newCar1的值也會更改
System.out.println("newCar1車子有 " + newCar1.wheel + " 個輪子");
System.out.println("newCar2車子有 " + newCar2.wheel + " 個輪子");
}
}
class Vehicle{ //定義的類別
int wheel; //定義一個實體變數
}
上面是附在光碟中的 code, 但是在我使用 Eclipse 編譯照抄時卻出現錯誤。
除了我不小心把 code 包到 main{}裏頭之外額外發現了其他寫法。
下面是我寫錯的程式段:
main{
class Vehicle{ //定義的類別
int wheel; //定義一個實體變數
}
}
說法一:
這是因為在 main {} 裏頭 Vehicle 是一個 動態 的內部類別,創建這樣的對象必須有實體與之對應,
程式是在靜態方法中直接調用動態內部類別所以會報出這樣錯誤。
這樣的錯誤好比類中的"靜態方法(static method)"不能直接調用動態方法。
所以可以把該內部類聲明為 static ,或者不要在靜態方法中調用他。
那麼......為啥非靜態方法不能調用動態方法呢?
從面向對象(ex: 物件)的角度來說,動態方法與對象(物件)是聯繫密切的,
比如:「發動」 是一個方法(method),它與「汽車」這個對象(物件)是關聯的,
所以只有 new 了汽車這個對象才能執行 汽車.發動
說法二:
內部類別實體依存於外部類別實體;
外部類別的靜態方法可以直接被調用,而不需要 new 外部類別實體;
所以在外部類別的靜態方法中直接實體化內部類別就會出現這個編譯錯誤。
上面是我在網路上看到關於錯誤的部分說明將之整理後的解釋。
所以我把 code 改成如下:
public class DefineClass2 {
//public int Vehicle;
public static void main(String args[])
{
class Vehicle // 定義類別
{
int wheel; // 定義一個實體變數
}
Vehicle newCar1 = new Vehicle(); // 實體化類別中物件
Vehicle newCar2 = new Vehicle(); // 同上
//「什麼是物件?」
// 物件是可以視為同一單位的程式碼和資料的組合。
// 物件可以是應用程式的一個片段,例如控制項或表單。
// 整個應用程式也可以是個物件。
//「什麼是變數?」
// 簡單的說,就是讓某一個特定字串代表不固定的內容就是了。
// 舉個大家在國中都會學到的數學例子,
那就是:『 y = ax + b 』這東西。
// 在等號左邊的(y)就是變數,在等號右邊的(ax+b)就是變數內容。
// 要注意的是,左邊是未知數,右邊是已知數喔!
// 講的更簡單一點,我們可以『用一個簡單的 "字眼"
來取代另一個比較複雜或者是容易變動的資料』。
// 這有什麼好處啊?最大的好處就是『方便!』。
Vehicle rCar; // 參考
rCar = newCar1; // rCar 指向 newCar1
newCar1.wheel = 4; // 指定一個值 給予 實體變數
newCar2.wheel = 8; // 同上
rCar.wheel = 6; // 因為 rCar 指向 newCar1 所以這裡會讓"6"取代前兩行所指定的值 = > "4"
System.out.println("newCar1 has " + newCar1.wheel + " tires.");
System.out.println("newCar2 has " + newCar2.wheel + " tires.");
}
}
2011年8月25日 星期四
[memo] JAVA 什麼是 Applet ?
Java Applet介紹
什麼是 Applet ?
Applet可以翻譯為小應用程序,
Java Applet就是用Java語言編寫的這樣的一些小應用程序,
它們可以直接嵌入到網頁中,並能夠產生特殊的效果。
包含Applet的網頁被稱為Java-powered頁,可以稱其為Java支持的網頁。
當用戶訪問這樣的網頁時, Applet被下載到用戶的計算機上執行,
但前提是用戶使用的是支持Java的網絡l瀏覽器。
由於Applet是在用戶的計算機上執行的,
因此它的執行速度不受網絡帶寬或者Modem存取速度的限制。
用戶可以更好地欣賞網頁上Applet產生的多媒體效果。
在Java Applet中,可以實現圖形繪製,字體和顏色控制,動畫和聲音的插入,
人機交互及網絡交流等功能。
Applet還提供了名為抽像窗口工具箱(Abstract Window Toolkit, AWT)的窗口環境開發工具。
AWT利用用戶計算機的GUI元素,可以建立標準的圖形用戶界面,如窗口、按鈕、滾動條等等。
目前在網絡上有非常多的Applet範例來生動地展現這些功能
讀者可以去調閱相應的網頁以觀看它們的效果。
Applet的工作原理?
含有Applet的網頁的HTML文件代碼中部帶有<applet> 和</applet>這樣一對標記,
當支持Java的網絡瀏覽器遇到這對標記時,
就將下載相應的小應用程序代碼並在本地計算機上執行該Applet。
例如下面是一個帶有 Applet 的首頁
1 <html>
2 <title>An Example Homepage </title>
3 <hl> Welcome to ddvip homepage! </hl>
4 This is an example homepage, you can see an applet in it。
5 <p>
6 <applet code=「Example.class」 width = 300 height=300>
7 <param name = img value="example.gif">
8 </applet>
9 <html>
上面這個例子就是一個簡單主頁的HTML文件代碼。
Code 第五行中的<P>,是為了確保Applet出現在新的一行,
也就是說,<P>的作用像一個回車符號(Enter),
若沒有它, Applet將會緊接著上一行的最後一個單詞出現。
Code 第六、七兩行是關於Applet的一些參數。
「第六行」是必需的Applet參數,
定義了編譯後的包含Applet字節碼的文件名,後綴通常為「.class」;
和以"像素"為單位的Applet的初始寬度與高度。
「第七行」則是附加的Applet參數,它由一個分離的<param>標記來指定其後的名稱和值,
在這裡是img的值為「example.gif',它代表了一個圖形文件名。
Applet 的下載與圖形文件一樣需要一定的時間,若干秒後它才能在屏幕上顯示出來。
等待的時間則取決於 Applet 的大小和用戶的網絡連接的速度。
一旦下載以後,它便和本地電腦上的程序以相同的速度運行了。
Applet在用戶的計算機上執行時,還可以下載其它的資源,
如聲音文件、圖像文件或更多的Java代碼,有些Applet還允許用戶進行交互式操作。
但這需要重複的鏈接與下載,因此速度很慢,
這是一個亟待解決的問題,可以想到的一個好辦法是採用類似高速緩存的技術,
將每次下載的文件都臨時保存在用戶的硬盤上,雖然第一次使用時花的時間比較多,
但當再次使用時,只需直接從硬盤上讀取文件而無需再與Internet連接,便可以大大提高性能了。
從哪裡得到App1et
自從Java日益流行之後,世界各地的愛好者們便不斷創造出各種各樣的Applet。
這裡列出了幾個較大的Applet收集站,讀者可以去逛一逛,
看看這些Applet的效果如何,相信會使人流連忘返的。
http://www.gamelan.com
這是Intemet上最負盛名的Applet收集站,它按照小應用程序的用途加以分類,
並列出了它們的說明、功能和程序代碼,其規模和種類之多,令人歎為觀止。
http://www.jars.com/
這個站點的特色是對它收集的小應用程序都加以評分,
JARS是小應用程序評價服務(Java Applet Rating Services)的簡稱。
許多Java開發者均以能獲得其好評為榮。
http://www.yahoo.com/Computers_and_Internet/Languages/Applet/
這個URL可真夠長的!
這是Yahoo公司提供的小應用程序目錄,收集的數量雖然稍遜於Gamelan,但也很可觀了。
http://home.netscape.com/comprod/products/navigator/version_2.0 /java_applets/
這是網景公司提供的小應用程序演示網頁,同時也提供一些Java信息。
http://java.wiwi.uni_frankfurt.de/
這是一個小應用程序的信息站點,提供了許多實用信息,
讀者可以借助這裡的數據庫,查詢自己感興趣的小應用程序的相關信息。
http://www.tech163.net/cx/jp/45428.htm
下載地址:
http://www.ibook8.com/Software/Catalog16/938.html
www.hnxa.com.cn/SoftView/SoftView_28192.html
2011年7月18日 星期一
[memo] JAVA 入門問題集
Q:什麼是 jdk ? 什麼是 jre ?
JDK
JDK 是整個Java的核心,包括了Java運行環境(Java Runtime
Envirnment),一堆Java工具和Java基礎的類庫(rt.jar)。不論什麼Java應用服務器實質都是內置了某個版本的JDK.最主流的
JDK是Sun公司發佈的JDK,除了Sun之外,還有很多公司和組織都開發了自己的JDK,例如IBM公司開發的JDK,BEA公司的Jrocket,
還有GNU組織開發的JDK等等。其中IBM的JDK包含的JVM(Java Virtual Machine)運行效率要比Sun
JDK包含的JVM高出許多。而專門運行在x86平台的Jrocket在服務端運行效率也要比Sun
JDK好很多。但不管怎麼說,我們還是需要先把Sun JDK掌握好。
JDK一般有三種版本:SE(J2SE),standard
edition,標準版,是我們通常用的一個版本EE(J2EE),enterpsise
edtion,企業版,使用這種JDK開發J2EE應用程序,ME(J2ME),micro
edtion,主要用於移動設備、嵌入式設備上的java應用程序Java開發工具(JDK)是許多Java專家最初使用的開發環境。儘管許多編程人員已
經使用第三方的開發工具,但JDK仍被當作Java開發的重要工具。JDK由一個標準類庫和一組建立,測試及建立文檔的Java實用程序組成。其核心
Java API是一些預定義的類庫,開發人員需要用這些類來訪問Java語言的功能。Java
API包括一些重要的語言結構以及基本圖形,網絡和文件I/O.一般來說,Java
API的非I/O部分對於運行Java的所有平台是相同的,而I/O部分則僅在通用Java環境中實現。
作為JDK實用程序,工具庫中有七種主要程序。
◆Javac:Java編譯器,將Java源代碼轉換成字節碼。
◆Java:Java解釋器,直接從類文件執行Java應用程序字節代碼。
◆appletviewer:小程序瀏覽器,一種執行HTML文件上的Java小程序的Java瀏覽器。
◆Javadoc:根據Java源碼及說明語句生成HTML文檔。
◆Jdb:Java調試器,可以逐行執行程序,設置斷點和檢查變量。
◆Javah:產生可以調用Java過程的C過程,或建立能被Java程序調用的C過程的頭文件。
◆Javap:Java反彙編器,顯示編譯類文件中的可訪問功能和數據,同時顯示字節代碼含義。
JRE
JRE(Java Runtime
Environment,Java運行環境),運行JAVA程序所必須的環境的集合,包含JVM標準實現及Java核心類庫。是Sun的產品,包括兩部
分:JavaRuntimeEnvironment和JavaPlug-inJavaRuntimeEnvironment(JRE)是可以在其上運行、
測試和傳輸應用程序的Java平台。它包括Java虛擬機、Java平台核心類和支持文件。它不包含開發工具——編譯器、調試器和其它工具。JRE需要輔
助軟件 ——JavaPlug-in——以便在瀏覽器中運行applet.J2RE是Java2 Runtime
Environment,即Java運行環境,有時簡稱JRE.如果你只需要運行Java程序或Applet,下載並安裝它即可。如果你要自行開發
Java軟件,請下載JDK.在JDK中附帶有JRE.注意由於Microsoft對Java的支持不完全,請不要使用IE自帶的虛擬機來運行
Applet,務必安裝一個JRE或JDK.
Q:Java "2"?
A:昇陽在1998年十二月發表了Java "2", 其實只是從版本1.2之後的稱為Java 2, 不用對這個'2'有太多的疑問.
參考連結:http://java.sun.com/products/jdk/1.2/java2.html
Q:JDK, SDK, JRE, 我到底要裝什麼?
A:JDK和SDK其實我們通常指的都是同一個東西, 而JDK與JRE的差別是, JDK可以拿來編譯你所寫的Java程式, 如果你想要學Java, 就請裝JDK, 如果只是要執行Java的程式, 你只要裝JRE就可以了. (JRE是JDK的子集)
Q:Java? JavaScript?
A:Java和JavaScript一點關係都沒有. 他們只不過是名字都有個Java.
套一句以前TAHO說的話, "熱狗和狗有關嗎?"
Q:Java不是號稱跨平台嗎? 為什麼還要裝JRE?
A:
因為用Java寫出來的程式是byte code, 要透過JVM(Java Virtual Machine)來執行,
其實跨平台的道理就是在不同的平台上裝上不同的JVM, 讓你的程式和平台中間多了一個中介. 所以你寫的程式在任何平台都可以執行(當然要是Pure
Java Code), 不過要有適合的JVM.
Q:學Java除了JDK, 還要有什麼?
A:Java的API相當的多, 普通人是沒有辦法全記下來的, 最好可以去sun下載Java API Doc回來, 以方便隨時查閱.
Q:寫Java程式要用什麼?
A:最簡單的就是記事本, 也可以用UltraEdit, Context, JCreator. 這些是初級的編輯器, 通常新手我個人還是不太建議直接使用IDE, 如JBuilder之類的, 那對新手可能有點吃力.
Q:要看什麼書?
A:
這個問題見人見智, 我建議先到天瓏書局看看朱仲傑的書, 其實我沒有看過, 不過它廣受好評, 至於侯捷先生所翻譯的Thinking in Java
2, 我有看過一些, 我覺得對於完全的新手來講可能有點難度, 建議是對Java已經有點瞭解, 或是寫過C/C++的人去看比較好.
我個人是認為Java太廣, 太大了, 光是一本書也是絕對不夠的, 在讀完一本書之後, 可以去看O'reilly針對各種主題的書(Java
networking, Java IO....), 循序漸進.
另外, 原文書中, Core Java 2也是不錯的書.
另外有一本有名的書, 是Deitel出的Java: How to program, 現在已經出到5th edition了,
不過我比較不建議這本書, 因為它到ch8, ch9才開始針對OO做完整的介紹, 我個人覺得不太好.
Q:J2SE, J2EE, J2ME到底分別是什麼?
A:J2SE是Java 2 Standard Edition, 新手都是從這個開始學
J2EE主要用在網路企業, 服務等, 而J2ME是用在小型行動裝置(手機、PDA...etc)
基本上J2SE是J2EE和J2ME的基礎.
Q:什麼是SDK ? 什麼是API ? 什麼是KIT ?
A:SDK是software development tool kit,翻譯成中文就是"軟體發展工具
組",通常是某一廠商針對某一平台或某一系統提供可以開發應用程式的工具組,
通常你問別人我想學SDK,他會問你要學什麼方面的SDK?(我就曾經問過這
樣的問題.)而微軟提供可開發window應用程式的SDK就是 win32/win64 API.
API是 application program interface 應用程式介面,它可提供一個一致的介面讓你設計你想要的應用程式,通常是一些function之類的東西.
API 目的是讓程式可以利用此介面來跟driver或是os作溝通
SDK:Soft develop kit 是開發軟體時才會用到的,一般user使用,是不用裝的。
SDK 是 軟體發展工具,K 就是 Kit 縮寫,意思就是"工具組"也是指 Windows 內建的"系統函數庫"。
早期,在 MS C 5/6/7 (1988 ~ 1993) 要在 DOS 下寫 Windows 程式只能使用 SDK 來實作,
直到 MS C 7 推出 MFC 1.0 後,開發 Windows 程式才變的輕鬆。現在已經變成 API 的說明書。
由於用法混亂,假設你同時看到這三個名詞,你可以這樣去分別:
1.API 為函數庫,你要直接控制某硬體或軟體時,需要使用
2.SDK 為說明書,說明 API 如何呼叫、如何使用
3.KIT 為工具組,可能有現成的範例或簡易工具,讓你不用寫程式也可以初步控制硬體。
2011年3月28日 星期一
[MEMO] Up/Down Casting & Java 字串比較
=======================Package 1==================================
public class ParsedResultType {
(中略)
public static final ParsedResultType ISBN = new ParsedResultType("ISBN");
/*
* 向上轉型: 將子類別建構的物件指派給父類別宣告的參考變數,
* 則該物件將會自動轉換為父類別的型別。
* 掃描後的結果內容。注意! 這個最終型態並非 "String"
*/
public static String EEEE;
public static String toString2() {
Object ISBN = new String ("ISBN");
EEEE = (String)ISBN;
return EEEE;
}
//向下轉型:將向上轉型為父類別型別的物件,再轉回,稱之。
}
=======================Package 2==================================
(前略)
public static final String AAAA = com.(略).ParsedResultType.EEEE;
public static final String CCCC = "9789862010228";
public void playBeepSoundAndVibrate()
{
if(CCCC.equals(AAAA))
/*
*不能用 if(AAAA.equals(CCCC))
*因為AAAA可能為null值,會彈出,java.lang.NullPointerException,。
*不能用 if (AAAA == CCCC)
*這是在比較兩個是否均為字串型別,結果必為true,所以不能拿來當作條件式
*/
{
if (playBeep && mediaPlayer != null)
{
mediaPlayer.start();
}
}
if (vibrate)
{
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
弔詭的地方來了,加入條件判斷之後他居然不會播放音效了......
準備來去看一下logcat = ="
2011年3月26日 星期六
[MEMO] Java import、package作用與用法
讓我們先瞭解一下,Java 的 package 到底有何用處。
其實,package 名稱就像是我們的姓,而 class 名稱就像是我們的名字
。package 名稱有很多 . 的,就好像是複姓。比如說 java.lang.String,就
是複姓 java.lang,名字為 String 的類別;java.io.InputStream 則是複姓
java.io,名字為 InputStream 的類別。
Java 會使用 package 這種機制的原因也非常明顯,就像我們取姓名一樣
,光是一間學校的同一屆同學中,就有可能會出現不少同名的同學,如果不取
姓的話,那學校在處理學生資料,或是同學彼此之間的稱呼,就會發生很大的
困擾。相同的,全世界的 Java 類別數量,恐怕比台灣人口還多,而且還不斷
的在成長當中,如果類別不使用套件名稱,那在用到相同名稱的不同類別時,
就會產生極大的困擾。幸運的是,Java 的套件名稱我們可以自己取,不像人
的姓沒有太大的選擇 ( 所以有很多同名同姓的 ),如果依照 Sun 的規範來取
套件名稱,那理論上不同人所取的套件名稱不會相同 ( 請參閱 "命名慣例"
的相關文章 ),也就不會發生名稱衝突的情況。
可是問題來了,因為很多套件的名稱非常的長,在寫程式時,會多打好多
字,花費不少時間,比如說:
java.io.InputStream is = java.lang.System.in;
java.io.InputStreamReader isr= new java.io.InputStreamReader(is);
java.io.BufferedReader br = new java.io.BufferedReader(isr);
實在是不美觀又麻煩。於是,Sun 想了一個辦法,就是 import。
這個 import 就是在程式一開頭的時候,先說明程式中會用到那些類別的
簡稱,也就是只稱呼名字,不稱呼他的姓。首先,在檔案開頭寫:
import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
這幾行說明了這四個姓名的類別,在程式中只用他的名字來稱呼,所以當程式
中提到 System 就是指 java.lang.System,而 InputStream 就是指
java.io.InputStream,依此類推。於是原來的程式就變成:
InputStream = System.in;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
這樣看起來是不是清爽多了呢?如果這些類別用的次數很多,那就更能體會到
import 的好處了。可是這樣還是不夠,因為懶是人的天性,還是會有人覺得
打太多 import 了也很浪費時間,於是 Sun 又提供了一個方法:
import java.lang.*;
import java.io.*;
意思就是,等一下程式中提到的沒有姓名的類別,不是姓 java.lang,就是姓
java.io,如果這兩個裡面有同樣名字的類別,而不幸的你又只用名字稱呼這
個類別,那編譯器仍然會跟你抱怨,因為它還是不知道你說的這個類別指那一
個姓的類別。那可不可以再懶一點呢,只寫:
import java.*;
歷史告訴我們,人可以懶,但不能太懶,這樣是不行的。因為那些類別是姓
java.io 而不是姓 java。就像姓『諸葛』的人應該不會喜歡你稱他為『諸』
先生吧。
為甚麼我一開始說 import 跟 #include 不同呢?因為 import 的功能
到此為止,它不像 #include 一樣,會將檔案內容載入進來。import 只是請
編譯器幫你打字,讓編譯器把沒有姓的類別加上姓,並不會把別的檔案的程
式碼寫進來。如果你想練習打字,可以不要使用 import,只要在用到類別的
時候,用它的全部姓名來稱呼它就行了(就像例子一開始那樣),跟使用
import 完全沒有甚麼兩樣。
另外,雖然人不可以太懶,但是 Sun 還是幫我們多偷了一點懶。因為
java.lang 這個套件實在是太常太常太常用到了,幾乎沒有程式不用它的,
所以不管你有沒有寫 import java.lang;,編譯器都會自動幫你補上,也就
是說編譯器只要看到沒有姓的類別,它就會自動去 java.lang 裡面找找看,
看這個類別是不是屬於這個套件的。所以我們就不用特別去
import java.lang 了。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
import導入聲明可分為兩中:
1>單類型導入(single-type-import)
例:import java.util.ArrayList;
2>按需類型導入(type-import-on-demand)
例:import java.util.*;
以這樣兩種方式導入包中的任何一個public的類和接口(只有public類和接口才能被導入)
*導入聲明僅導入類型而不導入子包;這就是為什麼稱它們為單類型導入和按需類型導入聲明的原因.
*導入的類或接口的簡名(simple name)具有編譯單元作用域.這表示該類型簡名可以在導入語句所在的編譯單元的任何地方使用.這並不意味著你可以使用該類型所有成員的簡名,而只能使用類型自身的簡名.
例如: java.lang包中的public類都是自動導入的,包括Math和System類.但是,你不能使用簡名PI()和gc(),而必須使用 Math.PI()和System.gc().你不需要鍵入的是java.lang.Math.PI()和java.lang.System.gc().
程序員有時會導入當前包或java.lang包,這是不需要的,因為當前包的成員本身就在作用域內,而java.lang包是自動導入的.java編譯器會忽略這些冗余導入聲明(redundant import declarations).即使像這樣
import java.util.ArrayList;
import java.util.*;
多次導入,也可編譯通過.編譯器會將冗余導入聲明忽略.
使用按需導入聲明是否會降低Java代碼的執行效率?絕對不會!
Java編譯器產生的類文件僅包含編譯單元實際使用到的類或接口的符號引用.
這是否意味著你總是可以使用按需導入聲明?是,也不是!
在類似Demo的非正式開發中使用按需導入聲明顯得很有用.
然而,有這四個理由讓你可以放棄這種聲明:
1>編譯速度:在一個很大的項目中,它們會極大的影響編譯速度.但在小型項目中使用在編譯時間上可以忽略不計.
2>命名衝突:解決避免命名衝突問題的答案就是使用全名.而按需導入恰恰就是使用導入聲明初衷的否定.
3>說明問題:全名的使用是自說性的.畢竟高級語言的代碼是給人看的.
4>無名包問題:如果在編譯單元的頂部沒有包聲明,Java編譯器首選會從無名包中搜索一個類型,然後才是按需類型聲明.如果有命名衝突就會產生問題.
Sun的工程師一般不使用按需類型導入聲明.這你可以在他們的代碼中找到:
在java.util.Properties類中的導入聲明:
import java.io.IOException;
import java.io.printStream;
import java.io.printWrite;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.Hashtable;
你可以看到有趣的是,她連java.util.Hashtable也導入,這可是在當前包中啊!
[MEMO] Java import、package作用與用法
轉貼自:Franklee
讓我們先瞭解一下,Java 的 package 到底有何用處。
其實,package 名稱就像是我們的姓,而 class 名稱就像是我們的名字
。package 名稱有很多 . 的,就好像是複姓。比如說 java.lang.String,就
是複姓 java.lang,名字為 String 的類別;java.io.InputStream 則是複姓
java.io,名字為 InputStream 的類別。
Java 會使用 package 這種機制的原因也非常明顯,就像我們取姓名一樣
,光是一間學校的同一屆同學中,就有可能會出現不少同名的同學,如果不取
姓的話,那學校在處理學生資料,或是同學彼此之間的稱呼,就會發生很大的
困擾。相同的,全世界的 Java 類別數量,恐怕比台灣人口還多,而且還不斷
的在成長當中,如果類別不使用套件名稱,那在用到相同名稱的不同類別時,
就會產生極大的困擾。幸運的是,Java 的套件名稱我們可以自己取,不像人
的姓沒有太大的選擇 ( 所以有很多同名同姓的 ),如果依照 Sun 的規範來取
套件名稱,那理論上不同人所取的套件名稱不會相同 ( 請參閱 "命名慣例"
的相關文章 ),也就不會發生名稱衝突的情況。
可是問題來了,因為很多套件的名稱非常的長,在寫程式時,會多打好多
字,花費不少時間,比如說:
java.io.InputStream is = java.lang.System.in;
java.io.InputStreamReader isr= new java.io.InputStreamReader(is);
java.io.BufferedReader br = new java.io.BufferedReader(isr);
實在是不美觀又麻煩。於是,Sun 想了一個辦法,就是 import。
這個 import 就是在程式一開頭的時候,先說明程式中會用到那些類別的
簡稱,也就是只稱呼名字,不稱呼他的姓。首先,在檔案開頭寫:
import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
這幾行說明了這四個姓名的類別,在程式中只用他的名字來稱呼,所以當程式
中提到 System 就是指 java.lang.System,而 InputStream 就是指
java.io.InputStream,依此類推。於是原來的程式就變成:
InputStream = System.in;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
這樣看起來是不是清爽多了呢?如果這些類別用的次數很多,那就更能體會到
import 的好處了。可是這樣還是不夠,因為懶是人的天性,還是會有人覺得
打太多 import 了也很浪費時間,於是 Sun 又提供了一個方法:
import java.lang.*;
import java.io.*;
意思就是,等一下程式中提到的沒有姓名的類別,不是姓 java.lang,就是姓
java.io,如果這兩個裡面有同樣名字的類別,而不幸的你又只用名字稱呼這
個類別,那編譯器仍然會跟你抱怨,因為它還是不知道你說的這個類別指那一
個姓的類別。那可不可以再懶一點呢,只寫:
import java.*;
歷史告訴我們,人可以懶,但不能太懶,這樣是不行的。因為那些類別是姓
java.io 而不是姓 java。就像姓『諸葛』的人應該不會喜歡你稱他為『諸』
先生吧。
為甚麼我一開始說 import 跟 #include 不同呢?因為 import 的功能
到此為止,它不像 #include 一樣,會將檔案內容載入進來。import 只是請
編譯器幫你打字,讓編譯器把沒有姓的類別加上姓,並不會把別的檔案的程
式碼寫進來。如果你想練習打字,可以不要使用 import,只要在用到類別的
時候,用它的全部姓名來稱呼它就行了(就像例子一開始那樣),跟使用
import 完全沒有甚麼兩樣。
另外,雖然人不可以太懶,但是 Sun 還是幫我們多偷了一點懶。因為
java.lang 這個套件實在是太常太常太常用到了,幾乎沒有程式不用它的,
所以不管你有沒有寫 import java.lang;,編譯器都會自動幫你補上,也就
是說編譯器只要看到沒有姓的類別,它就會自動去 java.lang 裡面找找看,
看這個類別是不是屬於這個套件的。所以我們就不用特別去
import java.lang 了。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
import導入聲明可分為兩中:
1>單類型導入(single-type-import)
例:import java.util.ArrayList;
2>按需類型導入(type-import-on-demand)
例:import java.util.*;
以這樣兩種方式導入包中的任何一個public的類和接口(只有public類和接口才能被導入)
*導入聲明僅導入類型而不導入子包;這就是為什麼稱它們為單類型導入和按需類型導入聲明的原因.
*導入的類或接口的簡名(simple name)具有編譯單元作用域.這表示該類型簡名可以在導入語句所在的編譯單元的任何地方使用.這並不意味著你可以使用該類型所有成員的簡名,而只能使用類型自身的簡名.
例如: java.lang包中的public類都是自動導入的,包括Math和System類.但是,你不能使用簡名PI()和gc(),而必須使用 Math.PI()和System.gc().你不需要鍵入的是java.lang.Math.PI()和java.lang.System.gc().
程序員有時會導入當前包或java.lang包,這是不需要的,因為當前包的成員本身就在作用域內,而java.lang包是自動導入的.java編譯器會忽略這些冗余導入聲明(redundant import declarations).即使像這樣
import java.util.ArrayList;
import java.util.*;
多次導入,也可編譯通過.編譯器會將冗余導入聲明忽略.
使用按需導入聲明是否會降低Java代碼的執行效率?絕對不會!
Java編譯器產生的類文件僅包含編譯單元實際使用到的類或接口的符號引用.
這是否意味著你總是可以使用按需導入聲明?是,也不是!
在類似Demo的非正式開發中使用按需導入聲明顯得很有用.
然而,有這四個理由讓你可以放棄這種聲明:
1>編譯速度:在一個很大的項目中,它們會極大的影響編譯速度.但在小型項目中使用在編譯時間上可以忽略不計.
2>命名衝突:解決避免命名衝突問題的答案就是使用全名.而按需導入恰恰就是使用導入聲明初衷的否定.
3>說明問題:全名的使用是自說性的.畢竟高級語言的代碼是給人看的.
4>無名包問題:如果在編譯單元的頂部沒有包聲明,Java編譯器首選會從無名包中搜索一個類型,然後才是按需類型聲明.如果有命名衝突就會產生問題.
Sun的工程師一般不使用按需類型導入聲明.這你可以在他們的代碼中找到:
在java.util.Properties類中的導入聲明:
import java.io.IOException;
import java.io.printStream;
import java.io.printWrite;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.Hashtable;
你可以看到有趣的是,她連java.util.Hashtable也導入,這可是在當前包中啊!
[MEMO] JAVA的18個基本概念
轉貼自:http://www.java1995.cn/article/926
關於Java的基礎知識,實踐證明學習OO,最終領悟「父類控制流程,子類實現具體的業務邏輯」的OO思想,需要的不是智商而是基礎,也就是說,基礎越好越快領悟,所以請每位S1學習Java的學員請牢記以下Java領域的基礎知識,最後祝各位學員在開發項目前可以領悟OO的真諦,老師也會竭盡全力助你們打通這道通向Java的極速大門。
1、 OO三大特性:繼承、封裝、多態(主要用於搭建程序框架,以此來提高代碼的重用性與解藕業務邏輯)。
2、 Java中的首字母大寫與命名規範:在Java中只有兩個地方會用到大寫的字母做為命名的第一個字母,一個是類,別一個是靜態變量。如:類Test、靜態 變量STATIC_NAME,如果Java使用的命名由幾個英文組成,則第二個開始的每個詞使用大寫隔開,如:userGroupId、 studentName。切忌:在Java中命名不能用中文與拼音,以及只有類名與靜態變量開頭的字母是使用大與,其他的命名如方法名、變量名一律開頭使 用小寫。
3、包(package):Java裡面的類太多了,你寫,我寫,大家寫,我們用的類名相同,不可能放在一起,怎麼辦?把它們放在不同的包裡面,就不會衝突了,包名為網址倒過來寫,請不要使用拼音來命名包名,以及包名不要過長(包的結構就是程序框架的結構).
4、 抽像類(abstract class): 前面加了 abstract 關鍵字修飾的類就是抽像類,抽像類不能生成實例(不能使用New關鍵字)只能拿來繼承,抽像類中一般包含抽像方法(作為債務產生),就是沒有具體實現的方法體(只做標示),一個類中如果定義了一個抽像方法這個類也就自動變成抽像類。
5、 抽像方法. 前面加了abstract 關鍵字修飾,沒有方法體.也就是方法什麼事也沒幹,像個空頭支票(產生債務方法之一).
6、 接口(interface): 接口可以理解為純抽像的類,它的每個方法都是未實現的,它就像一個產品的說明書(產生債務方法之一)。
7、 對像: 對象是存在的具體實體,就是按照類(汽車設計圖紙),做出來的真正的看得見摸得著的汽車(註:聲明一個對象就像一個變量名,如果使用了New關鍵字就已在內存中分配了地址).
8、 抽像:分析問題時抽出重要的因素,忽略掉不重要的(我們每天都在抽像身邊的事物,如:判斷一個人是好人還是壞人)。
9、靜態變量與方法(Static):所謂的靜態變量就是在定義時加一個Static的關鍵字,被定義為靜態的方法與變量是唯一的,也就是說不 管這個類有多少個實例化對像它們都共用這個類中的靜態變量或方法,這也是為什麼使用靜態變量或方法是用類名來直接調用的原因,而非靜態變量或方法等於每個 實例化對象都有自己的方法與變量,這樣就會互不影響。舉個例子:老師相當於靜態的,因為被所有學員所共有,而學員就是非靜態的,因為每個學員都是獨立的。
10、 Java的四種類型:
1.Public : 公共類型,在繼承時,父類定義為公共類型的方法或變量子類可以全部繼承過去,而且別的類可以隨意調用公共類型的方法和變量。
2.Private: 私用類型,在繼承時,父類定義為私用類型的函數或變量子類不能繼承,而且別的類不可調用私有類型的方法和變量。
3.Protected:保護類型,在繼承時,父類定義為保護類型的函數或變量子類可以全部繼承過去,只有它的子類可以在不同的包調用它的方法(與Default唯一不同的地方,Default不可以),在一個包下面可以全部被調用。
4.Default:默認類型,不加類型關鍵字會自動變成默認類型,繼承時父類定義為默認類型的函數或變量子類會全部繼承過去,但只有在一個包下面的類才能調用。
11、 封裝(Encapsulation )將重要的信息隱藏起來,或者將不需要使用者知道的很麻煩的信息全部藏起來,就像全自動洗衣機,只提供給用戶一個簡單的按鈕,把裡面具體的實現藏起來,使 用戶感覺操作很簡單(封裝有兩種方法接口與抽像類也叫基類,其中接口的封裝效果最好)。
12、 繼承(extends):子類可以繼承父類非私有的屬性和方法,就像兒子繼承老爸的財產,兒子可以少奮鬥二十年。
13、 多態(Polymorphism): 多態性是指「多種形式」也叫「動態綁定」它使用不同的子類來執行不同的操作,前提是子類中相關方法名必須是一樣,這樣通過New一個不同的子類,通過接口 或者父類就可以做到只修改一行代碼而做到實現不同的功能,因為對於子類來講方法名大家都是一樣的,就好像「畫圖」這個方法,每個不同形狀的圖形都 有,New一個圓進去就是畫圓,New一個正方型進去就是畫正方型,這是因為在這些不同形狀的圖中,他們都有一個一樣的方法叫「畫圖」,不同形狀的圖形在 自己的「畫圖」方法中實現自己的特色,這樣使用動態綁定,只需要修改很少的代碼就可以做到New什麼就畫什麼,這些就是多態。
14、 重載:當多個方法具有相同的名字而含有不同的參數個數或類型時,便發生重載.
15、重寫:子類繼承父類,子類和父類的方法具有相同的名稱和類型,但子類幹的事和父類幹的事不一樣。就像你和你老爸都有個方法叫—工作,但工作的內容不一樣,你搞軟件開發,你老爸是醫生.
16、 final 類:當一個類定義為 final 後,它將不能被其他類所繼承,在定義靜態變量時,一般 final 和 static 共同使用,這樣這個靜態變量就是不可變的。
17、父債子還:這是Java中關於方法重寫的一種硬性規定,就像欠賬還錢一樣。在這裡有兩種方法會產生債務,一個是抽像方法,另一個是接口中 的方法,大家會發現這兩種都有一個特性:它們定義的方法體都是空的,這就是產生了債務,所謂的償還債務只是繼承這個抽像類的子類或實現了某個接口的類,它 們必須要重寫這些空的方法體,否則編譯器會報錯。在這裡只有定義為抽像類才不用還債,空的方法是一定要重寫的,就像你不還錢,你的兒子也要還錢,你兒子不 還,你的孫子就要還,一直到錢還清了,這個時候你的子類才不用強制重寫任何方法。
18、 不能實例化:以下情況定義的類不可實例化(不能使用New關鍵字):抽像類、構造函數聲明為 private(私有)(不能繼承)
2011年3月2日 星期三
[MEMO] Java中this、super用法簡談
通過用static來定義方法或成員,爲我們編程提供了某種便利,從某種程度上可以說它類似于C語言中的全局函數和全局變量。
但是,並不是說有了這種便利,你便可以隨處使用,如果那樣的話,你便需要認真考慮一下自己是否在用面向對象的思想編程,自己的程序是否是面向對象的。
好了,現在開始討論 this&super這兩個關鍵字的意義和用法。
在Java中,this通常指當前對象,super則指父類別。
當你想要引用當前對象的某種東西,比如當前對象的某個方法,或當前對象的某個成員,你便可以利用this來實現這個目的。
當然,this的另一個用途是調用當前對象的另一個 構造函數,這些馬上就要討論。
如果你想引用父類的某種東西,則非super莫屬。
由於this與super有如此相似的一些特性和與生俱來的某種關系,所 以我們在這一塊兒來討論,希望能幫助你區分和掌握它們兩個。
在一般方法中最普遍的情況就是,在你的方法中的某個形參名與當前對象 的某個成員有相同的名字,這時爲了不至于混淆,你便需要明確使用this關鍵字來指明你要使用某個成員,使用方法是“this.成員名”,而不帶this 的那個便是形參。另外,還可以用“this.方法名”來引用當前對象的某個方法,但這時this就不是必須的了,你可以直接用方法名來訪問那個方法,編譯 器會知道你要調用的是那一個。下面的代碼演示了上面的用法:
==============================================================
public class DemoThis{
private String name;
private int age;
DemoThis(String name,int age){
setName(name);
//你可以加上this來調用方法,像這樣:this.setName(name);但這並不是必須的
setAge(age);
this.print(); br }
public void setName(String name){
this.name=name;
//此處必須指明你要引用成員變量
} public void etAge(int age){
this.age=age;
}
public void print(){
System.out.println("Name="+name+" ge="+age);
//在此行中並不需要用this,因爲沒有會導致混淆的東西
}
public static void main(String[] args)
{
DemoThis dt=new DemoThis("Kevin","22");
==============================================================
這段代碼很簡單,不用解釋你也應該能看明白。在構造函數中你看到用this.print(),你完全可以用print()來代替它,兩者效果一樣。下面我們修改這個程序,來演示super的用法。
==============================================================
class Person{
public int c;
private String name;
private int age; protected void setName(String name){
this.name=name;
}
protected void setAge(int age){
this.age=age;
} protected void print(){
System.out.println("Name="+name+" Age="+age); }}public class DemoSuper extends Person{
public void print(){
System.out.println("DemoSuper:");
super.print();}
public static void main(String[] args){
DemoSuper ds=new DemoSuper();
ds.setName("kevin");
ds.setAge(22);
ds.print(); }}
==============================================================
在DemoSuper中,重新定義的print方法覆寫了父類的print方法,它首先做一些自己的事情,然後調用父類的那個被覆寫了的方法。輸出結果說明了這一點:
DemoSuper:Name=kevin Age=22
這樣的使用方法是比較常用的。另外如果父類的成員可以被子類訪問,那你可以像使用this一樣使用它,用“super.父類中的成員名”的方式,但常常你並不是這樣來訪問父類中的成員名的。
在構造函數中構造函數是一種特殊的方法,在對象初始化的時候自動調用。在構造函數中,this和super也有上面說的種種使用方式,並且它還有特殊的地方,請看下面的例子:
==============================================================
class Person
{
public static void prt(String s)
{System.out.println(s);}
Person()
{prt("A Person."); }
Person(String name)
{prt("A person name is:"+name); }
}
public class Chinese extends Person{
Chinese()
{
super();
//調用父類構造函數(1)
prt("A chinese.");//(4)
}
Chinese(String name)
{
super(name);
//調用父類具有相同形參的構造函數(2)
prt("his name is:"+name);
}
Chinese(String name,int age)
{
this(name);
//調用當前具有相同形參的構造函數(3)
prt("his age is:"+age); }
public static void main(String[] args)
{
Chinese cn=new Chinese();
cn=new Chinese("kevin");
cn=new Chinese("kevin",22);
}
}
==============================================================
在這段程序中,this和super不再是像以前那樣用“.”連接一個方法或成員,而是直接在其後跟上適當的參數,因此它的意義也就有了變化。 super後加參數的是用來調用父類中具有相同形式的構造函數,如1和2處。this後加參數則調用的是當前具有相同參數的構造函數,如3處。當然,在 Chinese的各個重載構造函數中,this和super在一般方法中的各種用法也仍可使用,比如4處,你可以將它替換爲“this.prt”(因爲它繼承了父類中的那個方法)或者是“super.prt”(因爲它
是父類中的方法且可被子類訪問),它照樣可以正確運行。但這樣似乎就有點畫蛇添足的味道
了。
最後,寫了這麽多,如果你能對“this通常指代當前對象,super通常指代父類”這句話牢記在心,那麽本篇便達到了目的,其它的你自會在以後的編程實踐當中慢慢體會、掌握。另外關于本篇中提到的繼承,請參閱相關Java教程。
(王朝網絡 wangchao.net.cn)