您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java重要的關鍵字有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java重要的關鍵字有哪些”吧!
用于類繼承類,用法:class
+子類名+extends
+父類名+{}
class Animal{}//父類 class cat extends Animal{}//子類用extends實現繼承
注意:一個類只能用extends
關鍵字聲明繼承一個父類
用于接口繼承接口,用法:interface
+接口名+extends
+接口名+{}
interface Clippers {} interface Warriors {} interface Lakers extends Clippers,Warriors {}//接口類用extends關鍵字繼承其他接口(可多個)
注意:
接口不能用extends
聲明繼承別的類
接口只能用extends
聲明繼承別的接口,且可以繼承多個接口
當一個類用implements
實現了一個接口時,不僅要實現該接口的方法,也要實現該接口繼承的接口的方法
用于聲明一個類實現了一個接口類,用法:class
+類名+implements
+接口名+{}
class Nets implements Clippers,Warriors{}//用implements關鍵字聲明實現了兩個接口類
注意:
一個普通類可以implements
關鍵字聲明實現多個接口,但必須實現所有接口中的所有方法
抽象類實現接口,可以不用實現接口的方法(因為抽象類中可以有抽象方法)
意義:可以用implements
關鍵字聲明實現多個接口來實現類似多繼承
使用方法:
修飾類,使該類不能被繼承
修飾方法,使該方法不能被子類重寫 (仍可以被繼承和調用)
修飾屬性,使該屬性的值不能被修改(使為常量)
修飾局部變量,使該變量不能被修改(局部常量)
使用細節:
final
修飾的屬性在定義時必須賦初值,且不能修改,可以在以下位置賦初值
定義時(顯示初始化)
在構造器中
在代碼塊中
static final
:全局常量
如果final
修飾的屬性是靜態(static
)的,則不能在構造器中賦初值,原因:靜態屬性要求在類加載時就有初值,而構造器在創建對象時才被調用,所以可能導致調用靜態屬性時沒有創建對象而沒有給靜態屬性賦值
final
不能修飾構造方法,沒有意義
被final
和static
同時修飾的屬性在調用時不會導致類的加載,效率更高
基本介紹:
native
用來修飾方法,被修飾的方法即成為了一個Java調用但非Java代碼實現的接口(本地方法) ,該方法在外部可以用任何語言去實現
"A native method is a java method whose implementation is provided by non-java code."
使用方法:
native
修飾方法的位置必須在方法返回類型之前,和方法訪問修飾符位置沒有要求,如:public native int hashCode();
native
細節:
native
方法沒有方法體,也沒有{}
用native
修飾后的方法不能用abstract
修飾,因為abstract
指明該方法無實現體,而native
方法是有實現體的,只是用非Java
代碼實現的
native
方法的返回類型可以是任意類型
如果一個有native
方法的類被繼承,子類會繼承這個native
方法,并且可以用java
語言重寫
使用JNI(Java Native Interface)
與其他語言交互
JNI
是Java
平臺的一部分,它允許Java
代碼和其他語言寫的代碼進行交互。
使用步驟:
編寫帶有native
方法的java
類,生成.java
文件
使用javac
命令編譯生成.class
文件
使用javah -jni 類名
生成.h
文件
使用C/C++(或者其他編程語言)
實現native
方法,創建.cpp(或其他)
文件
將C/C++
編寫的文件創建動態鏈接庫(生成DLL文件)
native
方法中使用System.loadLibrary()
方法加載動態庫,將DLL文件名作為參數傳入,這時候再運行.java
程序即可實現對本地方法的調用
詳細步驟參考
native意義:
Java
無法直接訪問到操作系統底層(如系統硬件),但通過使用native
關鍵字修飾方法可以借用其他的語言來擴展Java
程序的功能,提高程序的效率
修飾變量,成為靜態變量或者類變量
使用方法:訪問修飾符+``static``+數據類型+變量名
注意事項:
靜態變量會被類的所有對象實例所共享,并且在類加載的時候就會初始化。
靜態變量的訪問方法(遵守相關訪問權限):類名.靜態變量名
或者 對象名.靜態變量名
修飾方法,成為靜態方法或者類方法
使用方法:訪問修飾符+``static``+返回數據類型+方法名+{}
注意事項:
調用方法(遵守相關訪問權限):類名.靜態方法名
或者 對象名.靜態方法名
靜態方法和普通方法都是隨著類加載而加載,將結構信息存儲在方法區
靜態方法中不允許使用this
和super
關鍵字
靜態方法中只能訪問靜態變量和靜態方法
普通方法可以訪問靜態成員和普通成員
修飾代碼塊,成為靜態代碼塊:
靜態代碼塊會在類加載時被加載,優先級和靜態屬性一樣,有多個靜態代碼塊和靜態屬性時,初始化順序按定義順序執行
好處:static
關鍵字的使用,將類中的一些成員修飾成靜態的,這樣我們不需要創建該類的對象就可以調用該成員,大大提高了編程效率
基本介紹:
transient
用于修飾實現了Serilizable
接口的類中的成員變量,在該類的實例對象進行序列化處理時,被transient
修飾的成員變量不會進行序列化。
使用例子:
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class outStream { public static void main(String[] args) throws IOException { String filePath = "d:\Cat.txt"; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath)); oos.writeObject(new Cat("小花貓", 3)); oos.close(); } } class Cat implements Serializable { private String name; private int age; //沒有用transient修飾 public Cat(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Car{" + "name='" + name + ''' + ", age=" + age + '}'; } } public class inStream { public static void main(String[] args) throws IOException, ClassNotFoundException { String filePath = "d:\Cat.txt"; ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath)); System.out.println(ois.readObject()); ois.close(); } }
可以在Cat.txt
文件內看到兩個成員變量都能被序列化,并且能被反序列化讀出信息。
當小花貓覺得自己的年齡是隱私不想被讀出時,用transient
修飾成員變量age
:
...... private String name; private transient int age; //使用transient修飾 ......
這時在Cat.txt
文件中可以看到只有name
一個成員變量被序列化,反序列化后的成員變量age
讀出的是int類型的默認值,說明對于transient
修飾的成員變量,在類的實例對象序列化的過程中會被忽略
transient
細節
對transient
修飾的成員變量可以理解為:不會參與進行對象的序列化和反序列化過程,生存周期僅存于調用者的內存而不會寫進磁盤里進行持久化
static
修飾的成員變量(靜態變量)也是不可序列化的,不論被transient
修飾與否
因為序列化是保存的實例對象的狀態,而靜態變量保存的是類的狀態
transient
關鍵字只能修飾變量,不能修飾方法和類
transient
關鍵字不能修飾局部變量
如transient
關鍵字修飾的是自定義類的變量,則該類需要實現Serilizable
接口
注意:
實現Serilizable
接口的類的實例對象是自動進行序列化的,如果序列化對象的類實現的是Externalizable
接口,則序列化不會自動進行,需要實現接口內的方法指定要序列化的變量,這時與有無Transient
修飾無關
基本介紹:
關鍵字synchronized
可以保證在同一時刻,只有一個線程可以執行被synchronized
修飾的方法或代碼塊
線程同步:
程序中多個線程都要使用同一個方法,而這個方法用synchronized
進行了修飾,在多個線程調用這個方法時必須遵循同步機制
線程同步機制:
當一個線程使用synchronized
修飾的方法時,其他線程想使用這個方法時就必須等待,直到這個線程使用完synchronized
方法
synchronized使用方法:
普通同步方法:public synchronized void m () {}
public class syn implements Runnable { static int i = 0; public static void main(String[] args) throws InterruptedException { syn test = new syn(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.start(); t2.start(); } public synchronized void increase() {//被synchronized修飾的同步方法 System.out.println(Thread.currentThread().getName() + "調用:" + i++); } @Override public void run() { for (int j = 0; j < 100; j++) { increase(); } } }
兩個線程同時調用一個對象的一個同步方法,由于一個對象只有一把鎖,所以只有一個線程能夠獲得該對象的鎖,另一個線程無法獲得,就不能調用該對象的synchronized
方法,需要等對象被釋放后才能調用。
從運行結果中可以證明線程1搶到了鎖,線程0必須等待線程1執行完畢,否則不能訪問該同步方法。
靜態同步方法:public static synchronized void m () {}
public class syn implements Runnable { static int i = 0; public static void main(String[] args) throws InterruptedException { syn test = new syn(); syn test1 = new syn(); Thread t1 = new Thread(test);//傳入實例對象test Thread t2 = new Thread(test1);//傳入實例對象test1 t1.start(); t2.start(); } public static synchronized void increase() {//同步靜態方法 System.out.println(Thread.currentThread().getName() + "調用:" + i++); } @Override public void run() { for (int j = 0; j < 100; j++) { increase(); } } }
雖然兩個線程實例化了兩個不同的對象,但是synchronized
修飾的是靜態方法,兩個線程仍然發生了互斥,因為靜態方法是依附與類的而不是對象,線程1先搶到了類的鎖,而線程0必須等待線程1執行完畢釋放才能調用同步方法
同步代碼塊:synchronized(object) {}
public class syn implements Runnable { static Object object = new Object();//共享對象 public static void main(String[] args) throws InterruptedException { syn test = new syn(); syn test1 = new syn(); Thread t1 = new Thread(test); Thread t2 = new Thread(test1); t1.start(); t2.start(); } @Override public void run() { synchronized (object) {//代碼塊用靜態成員變量上鎖 for (int j = 0; j < 100; j++) { System.out.println(Thread.currentThread().getName() + "調用第" + j + "次"); } } } }
同步代碼塊用兩個實例變量共享的靜態成員object
對象來上鎖,雖然是兩個線程實例化兩個不同的對象,但是對整個syn
類來說只有一個共享的object
對象,所以只有一把鎖,每當有線程來訪問代碼塊時需持有鎖,對象鎖被其他線程持有時需等待。線程1需要等線程0執行完畢才能訪問同步代碼塊
同步的局限性:
由于同步的方法或代碼塊只能同一時間讓一個線程訪問,所以會導致程序的執行效率降低
盡可能讓synchronized
修飾的范圍最小化,來減少互斥對程序執行帶來的影響
8.volatile
基本介紹:
volatile
用于修飾變量,用volatile
修飾的變量的值被某個線程修改時,會強制將修改的值立即寫入主存中,主存中的值更新會使得緩存中的該變量的值失效,對比與非volatile
變量,可能會被其他線程讀取到更新前的值。
使用方法:
//現在有線程1和線程2同時執行下列代碼 int i = 0; i = i + 1;
執行完畢后預想的結果是 i = 2
;但是可能存在這樣一種情況:兩個線程先同時把i的值讀取到自己的工作內存中,然后再分別執行 i = i + 1
的操作,再將結果寫入主存,這樣兩個線程寫入的都是 i = 1
,最終 i
的結果是 1
,而不是 2
但如果 i
是 volatile
修飾的變量就會不一樣了,在一個線程修改 i
的值后,會立即強制在主存中更新 i
的值,這樣會導致另一個線程的工作內存中 i
的緩存值無效,所以另一個線程再次從主存中讀取新的 i
的值,這樣保證了i
的值是最新并正確的
并發編程的三大概念:
原子性:執行一個操作時,要么全部步驟執行完畢且不被中斷,要么就不執行
x = 100;//是原子性操作 y = x;//不是原子性操作,可分解為:1.先讀取x的值 2.將x的值寫入主存 x ++;//不是原子性操作,可分解為:1.讀取x的值 2.進行加一操作 3.寫入主存
可見性:多個線程對同一個變量進行操作時,一個線程修改了變量的值,其他線程能立即看到修改的值
有序性:程序執行的順序按照代碼的先后順序執行
volatile
的意義
保證了不同線程對變量進行修改時的可見性:因為對于volatile
變量來說,被修改后新值對其他線程來說是立即可見的
保證了有序性:volatile
禁止了指令重排,它能保證在對volatile
修飾的變量進行操作時,之前的代碼語句已經全部被執行,并且后面的語句都未執行,但是對其他語句的順序是不做保證的
注意: volatile
不能保證原子性,因為不能保證對變量的操作是原子性操作
在方法中修飾屬性,this理解為當前對象
,用來區別成員方法和形參,通常省略
修飾方法,this理解為當前對象,通常省略;不能在靜態方法中使用
調用構造器,在構造器中使用this(形參列表)
顯式調用指定的其他構造器
必須在首行調用其他構造器
一個構造器中不能調用多個其他構造器
不能在構造器中調用遞歸調用,不能成環調用
super可以理解為:父類的
修飾屬性:去父類中找對應屬性,用來區分子父類重名的屬性
修飾方法:調用重寫之前的方法
調用構造器:使用super(形參列表)
指定調用父類構造器
super(形參列表)
必須放在構造器的首行
super(形參列表)
和this(形參列表)
只能二選一
在構造器首行如果沒有顯式聲明super(形參列表)
或this(形參列表)
則默認調用父類的空參構造器super()
(如果此時父類中沒有空參構造器就會報錯)
不能在靜態方法中使用
當一個方法和屬性被static屬性修飾時,這些方法和屬性是優先于對象加載進入內存的,是隨著類的加載而加載的;this是當前對象的引用,super是指父類的引用,當靜態方法加載進內存進棧時,如果在靜態方法中有this和super關鍵字時,this和super也被加載到了內存,但是這個時候并沒有對象的引用,this和super沒有初始化,所有編譯會報錯。
public修飾類:
一個類中最多只能有一個public類,且文件名要和public類一致
如果沒有public類,文件名可以任意
感謝各位的閱讀,以上就是“Java重要的關鍵字有哪些”的內容了,經過本文的學習后,相信大家對Java重要的關鍵字有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。