第四章、Java保留關鍵字
Java語言有51個保留關鍵字,其中const和goto雖然被保留但未被使用。你不能使用保留關鍵字來命名類、方法或變量。
一、保留關鍵字
數據類型:
Boolean int long short byte float double char class interface
流程控制:
if else do while for switch case default break continue return try catch finally
修飾符:
public protected private final void static strictfp abstract transient
synchronized volatile native
動作:
package import throw throws extends implements this Super instanceof new
保留字:
true false null goto const
二、訪問修飾符:
訪問修飾符: public , protected , private
* 只能應用於類的成員變量。(局部變量只能在函數的範圍內可見,不能使用訪問修飾符)
* 能夠用來修飾類本身。(protected , private 不能用於頂級類,只能用於內部類)
* 能夠應用於成員方法和構造函數。
下面是一個例子:
package Examples;
public class HelloWorld02{
//以下定義了三個了類成員變量
public String str1="Hello"; //可被你程序中的任何其他代碼訪問
protected String str2="World!"; //程序中同一包的成員和不同包中的該類子類可以訪問
private String str3=" "; //僅該類中的成員可以訪問
String str=str1+str3+str2; //不使用修飾符的話,變量的訪問控制在所在包內爲public,
// 不能被所在包外的代碼存取
//以下定義了三個使用不同修飾符和不同參數的構造方法。
public HelloWorld(){
System.out.println(str);
}
protected HelloWorld(long l){
System.out.print("Use /"protected/" constructor! And l is ["+l+"] ");
System.out.println(str);
}
private HelloWorld(float f){
System.out.print("Use /"private/" constructor! And f is ["+f+"] ");
System.out.println(str);
}
//聲明構造方法爲void類型是合法的.不過因爲沒有返回值,所以不能用來創建新對象.
public void HelloWorld(){
System.out.println(str +" Use the void constructor!");
}
public static void main(String[] args){
HelloWorld hw1=new HelloWorld(); //使用無參數的構造方法
HelloWorld hw2=new HelloWorld(5); // 雖然5是int類型,但會自動提升成long類型
HelloWorld hw3=new HelloWorld(5L);
HelloWorld hw5=new HelloWorld(3.14f); // 但float類型則必須指明,否則會出錯
hw5.HelloWorld(); // 無返回值的構造方法只能這樣調用
(new HelloWorld()).HelloWorld(); //這裏創建了一個匿名類對象並調用無返回值的構造方法
}
}
總結:
請認真思考一下:
(1)public、protected、private 可用來修飾哪些成員?
使用這些修飾符的成員的訪問控制是怎樣的?
沒有指定訪問修飾符的成員的訪問控制是怎樣的?
* public、protected和private可以用來修飾類成員變量、方法、構造方法和內部類;
public可以用來修飾頂級類,但protected和private則不行。
*類成員訪問控制可見下表:
|
Private成員 |
默認成員 |
Protected成員 |
Public成員 |
同一類中可見 |
是 |
是 |
是 |
是 |
同一包中對子類可見 |
否 |
是 |
是 |
是 |
同一包中對非子類可見 |
否 |
是 |
是 |
是 |
不同包中對子類可見 |
否 |
否 |
是 |
是 |
不同的包中對非子類可見 |
否 |
否 |
否 |
是 |
簡單總結一下,(按它們的訪問範圍由大到小排列):
public: 任何地方均可訪問
protected:同一包和子類可見
默認: 同一包中可見
private: 僅該類內部可見
注意事項:
* 每一個java文件中可以包含多個類,但只能存在一個public頂級類,如果聲明瞭兩個頂級類的話,則會出現編譯錯誤。
二、部分其他修飾符
this:
Java中定義了this關鍵字來訪問當前對象實例內的成員。當局部變量和類實例內的類變量同名時,在這個局部變量所作用區域內類變量就被隱藏了,必須使用this來指明。
static:
有時你希望定義一個類成員,使它的使用完全獨立於該類的任何對象。通常情況下,類成員必須通過它的類的對象訪問,但是可以創建這樣一個成員,它能夠被它所在類使用,而不必引用所在類的實例。將類中的成員聲明爲static就能實現這樣的效果。聲明爲static的變量實質就是全局變量。當聲明一個對象(某個類的實例)時,並不產生static變量的拷貝,而是該類所有的實例變量共用同一個static變量。
聲明爲static的方法有以下三條限制:
* 它們只能訪問static數據
* 它們僅能調用其他的static方法
* 它們不能以任何方式引用this或super
實例分析:
package Examples;
public class StaticDemo{
public static void main(String[] args){
System.out.println(MyStaticClass.str); //不用創建MyStaticClass的實例就能訪問它的str變量
// System.out.println(MyStaticClass.str2); 這句是錯誤的。
MyStaticClass msc=new MyStaticClass(); //這裏創建MyStaticClass的一個實例
System.out.println("After create instance:");
msc.printString();
}
}
class MyStaticClass{
static String str="Hello World!";
String str2;
void setString(String s){
str2=s;
}
static void setNewString(String s){
str=s;
}
static void printString(){
//setString(str); 在static方法中調用非static方法是錯誤的
//System.out.println(str2); 也不能訪問非static變量
//Java中是先檢測static變量再檢測static方法的
System.out.println(str); // 可以正常訪問static變量
setNewString("Static method is OK!"); //正常調用static方法
System.out.println(str);
}
}
final:
一個變量可以被聲明爲final,這樣做的目的是阻止它的內容被修改。這意味着在聲明final變量的時候,你必須初始化它。一個final變量實質上是一個常數,爲final變量的所有字母選擇大寫是一個普遍的編碼約定。聲明爲final的變量在實例中不佔用內存。
聲明成final的方法不能被重載。通常,Java在運行時動態的調用方法,這叫做後期綁定(late binding);由於被聲明爲final的方法不能被重載,那麼對final方法的調用可以在編譯時解決,這叫做早期綁定(early bingding)。
聲明爲final的類不能被其他類繼承。聲明一個final類含蓄的宣告了它的所有方法也都是final的。所以,聲明一個既是abstract的,又是final的類是不合法的,因爲抽象類本身是不完整的,它依靠它的子類提供完整的實現。
strictfp:
Java2向Java語言增加了一個新的關鍵字strictfp。與Java2同時產生的浮點運算計算模型很輕鬆的使某些處理器可以以較快速度進行浮點運算(例如奔騰處理器)。這個浮點運算計算模型在計算過程中,不需要切斷某些中介值。如果用strictfp來修飾類或方法,可以確保浮點運算(以及所有切斷)正如它們在早期Java版本中那樣準確(即使用原始的浮點運算模型)。切斷隻影響某些操作的指數。當一個類被strictfp修飾,所有該類的方法都自動被strictfp修飾。坦白說,很多程序員從未用過strictfp,因爲它只對非常少的問題有影響。
native:
有時你希望調用不是用Java語言寫的子程序,或者你希望調用一個專用的第三方的庫,例如統計學包。雖然這種情況比較少,但Java提供了native關鍵字,該關鍵字用來聲明本機代碼方法。
爲聲明一個本機方法,在該方法之前用native修飾符,但是不要定義任何方法體。例如:
public native int meth();
聲明本機方法後,必須編寫本機方法並要執行一系列複雜的步驟使它與Java代碼鏈接。很多本機方法是用C寫的。把C代碼結合到Java程序中的機制是調用Java Native Interface(JNI)。
transient:
如果用transient聲明一個實例變量,當對象儲存時,它的值不需要維持。例如:
class T{
transient int a; // will not persist
int b; // will persist
}
這裏,如果T類的一個對象被寫入一個持久的存儲區域,a的內容不被保存,但b將被保存。
volatile:(不是很明白,待研究)
volatile修飾符告訴編譯器被volatile修飾的變量可以被程序的其他部分改變。一種 這樣的情形是多線程程序。在多線程程序裏,有時兩個或更多的線程共享一個相同的實例變量。考慮效率的問題,每個線程可以自己保存該共享變量的私有拷貝。實際的(或主要的)變量副本在不同的時候更新,例如當進入synchronized方法時。當這種方法運行良好時,它在時間上會是低效的。在某些情況下,真正要緊的是變量主副本的值會體現當前的狀態。爲保證這點,僅需把變量定義成volatile型,它告訴編譯器它必須總是使用volatile變量的主副本(或者至少總是保持一些私有的最新的主副本的拷貝,反之亦然),同時,對主變量的獲取必須以簡潔次序執行,就像執行私有拷貝一樣。