Java幾個重要的關鍵字詳析
1.extends
- 用于類繼承類,用法:
class+子類名+extends+父類名+{}
class Animal{}//父類
class cat extends Animal{}//子類用extends實現(xiàn)繼承 注意:一個類只能用extends關鍵字聲明繼承一個父類
- 用于接口繼承接口,用法:
interface+接口名+extends+接口名+{}
interface Clippers {}
interface Warriors {}
interface Lakers extends Clippers,Warriors {}//接口類用extends關鍵字繼承其他接口(可多個)注意:
- 接口不能用
extends聲明繼承別的類 - 接口只能用
extends聲明繼承別的接口,且可以繼承多個接口 - 當一個類用
implements實現(xiàn)了一個接口時,不僅要實現(xiàn)該接口的方法,也要實現(xiàn)該接口繼承的接口的方法
2.implements
- 用于聲明一個類實現(xiàn)了一個接口類,用法:
class+類名+implements+接口名+{}
class Nets implements Clippers,Warriors{}//用implements關鍵字聲明實現(xiàn)了兩個接口類注意:
- 一個普通類可以
implements關鍵字聲明實現(xiàn)多個接口,但必須實現(xiàn)所有接口中的所有方法 - 抽象類實現(xiàn)接口,可以不用實現(xiàn)接口的方法(因為抽象類中可以有抽象方法)
- 意義:可以用
implements關鍵字聲明實現(xiàn)多個接口來實現(xiàn)類似多繼承
3.final
使用方法:
- 修飾類,使該類不能被繼承
- 修飾方法,使該方法不能被子類重寫 (仍可以被繼承和調(diào)用)
- 修飾屬性,使該屬性的值不能被修改(使為常量)
- 修飾局部變量,使該變量不能被修改(局部常量)
使用細節(jié):
final修飾的屬性在定義時必須賦初值,且不能修改,可以在以下位置賦初值
- 定義時(顯示初始化)
- 在構造器中
- 在代碼塊中
static final:全局常量
- 如果
final修飾的屬性是靜態(tài)(static)的,則不能在構造器中賦初值,原因:靜態(tài)屬性要求在類加載時就有初值,而構造器在創(chuàng)建對象時才被調(diào)用,所以可能導致調(diào)用靜態(tài)屬性時沒有創(chuàng)建對象而沒有給靜態(tài)屬性賦值 final不能修飾構造方法,沒有意義- 被
final和static同時修飾的屬性在調(diào)用時不會導致類的加載,效率更高
4.native
基本介紹:
native用來修飾方法,被修飾的方法即成為了一個Java調(diào)用但非Java代碼實現(xiàn)的接口(本地方法) ,該方法在外部可以用任何語言去實現(xiàn)
"A native method is a java method whose implementation is provided by non-java code."
使用方法:
native修飾方法的位置必須在方法返回類型之前,和方法訪問修飾符位置沒有要求,如:public native int hashCode();
native細節(jié):
native方法沒有方法體,也沒有{}- 用
native修飾后的方法不能用abstract修飾,因為abstract指明該方法無實現(xiàn)體,而native方法是有實現(xiàn)體的,只是用非Java代碼實現(xiàn)的 native方法的返回類型可以是任意類型- 如果一個有
native方法的類被繼承,子類會繼承這個native方法,并且可以用java語言重寫
使用JNI(Java Native Interface) 與其他語言交互
JNI是Java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。

使用步驟:
- 編寫帶有
native方法的java類,生成.java文件 - 使用
javac命令編譯生成.class文件 - 使用
javah -jni 類名生成.h文件 - 使用
C/C++(或者其他編程語言)實現(xiàn)native方法,創(chuàng)建.cpp(或其他)文件 - 將
C/C++編寫的文件創(chuàng)建動態(tài)鏈接庫(生成DLL文件) native方法中使用System.loadLibrary()方法加載動態(tài)庫,將DLL文件名作為參數(shù)傳入,這時候再運行.java程序即可實現(xiàn)對本地方法的調(diào)用
native意義:
Java無法直接訪問到操作系統(tǒng)底層(如系統(tǒng)硬件),但通過使用native關鍵字修飾方法可以借用其他的語言來擴展Java程序的功能,提高程序的效率
5.static
修飾變量,成為靜態(tài)變量或者類變量
- 使用方法:
訪問修飾符+``static``+數(shù)據(jù)類型+變量名
注意事項:
- 靜態(tài)變量會被類的所有對象實例所共享,并且在類加載的時候就會初始化。
- 靜態(tài)變量的訪問方法(遵守相關訪問權限):
類名.靜態(tài)變量名或者對象名.靜態(tài)變量名
修飾方法,成為靜態(tài)方法或者類方法
- 使用方法:
訪問修飾符+``static``+返回數(shù)據(jù)類型+方法名+{}
注意事項:
- 調(diào)用方法(遵守相關訪問權限):
類名.靜態(tài)方法名或者對象名.靜態(tài)方法名 - 靜態(tài)方法和普通方法都是隨著類加載而加載,將結構信息存儲在方法區(qū)
- 靜態(tài)方法中不允許使用
this和super關鍵字 - 靜態(tài)方法中只能訪問靜態(tài)變量和靜態(tài)方法
- 普通方法可以訪問靜態(tài)成員和普通成員
- 修飾代碼塊,成為靜態(tài)代碼塊:
靜態(tài)代碼塊會在類加載時被加載,優(yōu)先級和靜態(tài)屬性一樣,有多個靜態(tài)代碼塊和靜態(tài)屬性時,初始化順序按定義順序執(zhí)行
好處:static關鍵字的使用,將類中的一些成員修飾成靜態(tài)的,這樣我們不需要創(chuàng)建該類的對象就可以調(diào)用該成員,大大提高了編程效率
6.transient
基本介紹:
transient用于修飾實現(xiàn)了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文件內(nèi)看到兩個成員變量都能被序列化,并且能被反序列化讀出信息。
當小花貓覺得自己的年齡是隱私不想被讀出時,用transient修飾成員變量age:
...... private String name; private transient int age; //使用transient修飾 ......


這時在Cat.txt文件中可以看到只有name一個成員變量被序列化,反序列化后的成員變量age讀出的是int類型的默認值,說明對于transient修飾的成員變量,在類的實例對象序列化的過程中會被忽略
transient細節(jié)
- 對
transient修飾的成員變量可以理解為:不會參與進行對象的序列化和反序列化過程,生存周期僅存于調(diào)用者的內(nèi)存而不會寫進磁盤里進行持久化 static修飾的成員變量(靜態(tài)變量)也是不可序列化的,不論被transient修飾與否
因為序列化是保存的實例對象的狀態(tài),而靜態(tài)變量保存的是類的狀態(tài)
transient關鍵字只能修飾變量,不能修飾方法和類transient關鍵字不能修飾局部變量- 如
transient關鍵字修飾的是自定義類的變量,則該類需要實現(xiàn)Serilizable接口
注意:
實現(xiàn)Serilizable接口的類的實例對象是自動進行序列化的,如果序列化對象的類實現(xiàn)的是Externalizable接口,則序列化不會自動進行,需要實現(xiàn)接口內(nèi)的方法指定要序列化的變量,這時與有無Transient修飾無關
7.synchronized
基本介紹:
關鍵字synchronized可以保證在同一時刻,只有一個線程可以執(zhí)行被synchronized修飾的方法或代碼塊
線程同步:
程序中多個線程都要使用同一個方法,而這個方法用synchronized進行了修飾,在多個線程調(diào)用這個方法時必須遵循同步機制
線程同步機制:
當一個線程使用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() + "調(diào)用:" + i++);
}
@Override
public void run() {
for (int j = 0; j < 100; j++) {
increase();
}
}
}
兩個線程同時調(diào)用一個對象的一個同步方法,由于一個對象只有一把鎖,所以只有一個線程能夠獲得該對象的鎖,另一個線程無法獲得,就不能調(diào)用該對象的synchronized方法,需要等對象被釋放后才能調(diào)用。
從運行結果中可以證明線程1搶到了鎖,線程0必須等待線程1執(zhí)行完畢,否則不能訪問該同步方法。
- 靜態(tài)同步方法:
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() {//同步靜態(tài)方法
System.out.println(Thread.currentThread().getName() + "調(diào)用:" + i++);
}
@Override
public void run() {
for (int j = 0; j < 100; j++) {
increase();
}
}
}
雖然兩個線程實例化了兩個不同的對象,但是synchronized修飾的是靜態(tài)方法,兩個線程仍然發(fā)生了互斥,因為靜態(tài)方法是依附與類的而不是對象,線程1先搶到了類的鎖,而線程0必須等待線程1執(zhí)行完畢釋放才能調(diào)用同步方法
- 同步代碼塊:
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) {//代碼塊用靜態(tài)成員變量上鎖
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + "調(diào)用第" + j + "次");
}
}
}
}
同步代碼塊用兩個實例變量共享的靜態(tài)成員object對象來上鎖,雖然是兩個線程實例化兩個不同的對象,但是對整個syn類來說只有一個共享的object對象,所以只有一把鎖,每當有線程來訪問代碼塊時需持有鎖,對象鎖被其他線程持有時需等待。線程1需要等線程0執(zhí)行完畢才能訪問同步代碼塊
同步的局限性:
由于同步的方法或代碼塊只能同一時間讓一個線程訪問,所以會導致程序的執(zhí)行效率降低
盡可能讓synchronized修飾的范圍最小化,來減少互斥對程序執(zhí)行帶來的影響
8.volatile
基本介紹:
volatile用于修飾變量,用volatile修飾的變量的值被某個線程修改時,會強制將修改的值立即寫入主存中,主存中的值更新會使得緩存中的該變量的值失效,對比與非volatile變量,可能會被其他線程讀取到更新前的值。
使用方法:
//現(xiàn)在有線程1和線程2同時執(zhí)行下列代碼 int i = 0; i = i + 1;
執(zhí)行完畢后預想的結果是 i = 2;但是可能存在這樣一種情況:兩個線程先同時把i的值讀取到自己的工作內(nèi)存中,然后再分別執(zhí)行 i = i + 1 的操作,再將結果寫入主存,這樣兩個線程寫入的都是 i = 1,最終 i 的結果是 1 ,而不是 2
但如果 i 是 volatile 修飾的變量就會不一樣了,在一個線程修改 i的值后,會立即強制在主存中更新 i 的值,這樣會導致另一個線程的工作內(nèi)存中 i 的緩存值無效,所以另一個線程再次從主存中讀取新的 i 的值,這樣保證了i的值是最新并正確的
并發(fā)編程的三大概念:
- 原子性:執(zhí)行一個操作時,要么全部步驟執(zhí)行完畢且不被中斷,要么就不執(zhí)行
x = 100;//是原子性操作 y = x;//不是原子性操作,可分解為:1.先讀取x的值 2.將x的值寫入主存 x ++;//不是原子性操作,可分解為:1.讀取x的值 2.進行加一操作 3.寫入主存
- 可見性:多個線程對同一個變量進行操作時,一個線程修改了變量的值,其他線程能立即看到修改的值
- 有序性:程序執(zhí)行的順序按照代碼的先后順序執(zhí)行
volatile的意義
- 保證了不同線程對變量進行修改時的可見性:因為對于
volatile變量來說,被修改后新值對其他線程來說是立即可見的 - 保證了有序性:
volatile禁止了指令重排,它能保證在對volatile修飾的變量進行操作時,之前的代碼語句已經(jīng)全部被執(zhí)行,并且后面的語句都未執(zhí)行,但是對其他語句的順序是不做保證的
注意: volatile不能保證原子性,因為不能保證對變量的操作是原子性操作
9.this
- 在方法中修飾屬性,this理解為
當前對象,用來區(qū)別成員方法和形參,通常省略 - 修飾方法,this理解為當前對象,通常省略;不能在靜態(tài)方法中使用
- 調(diào)用構造器,在構造器中使用
this(形參列表)顯式調(diào)用指定的其他構造器- 必須在首行調(diào)用其他構造器
- 一個構造器中不能調(diào)用多個其他構造器
- 不能在構造器中調(diào)用遞歸調(diào)用,不能成環(huán)調(diào)用
10.super
super可以理解為:父類的
- 修飾屬性:去父類中找對應屬性,用來區(qū)分子父類重名的屬性
- 修飾方法:調(diào)用重寫之前的方法
- 調(diào)用構造器:使用
super(形參列表)指定調(diào)用父類構造器super(形參列表)必須放在構造器的首行super(形參列表)和this(形參列表)只能二選一- 在構造器首行如果沒有顯式聲明
super(形參列表)或this(形參列表)則默認調(diào)用父類的空參構造器super()(如果此時父類中沒有空參構造器就會報錯)
- 不能在靜態(tài)方法中使用
當一個方法和屬性被static屬性修飾時,這些方法和屬性是優(yōu)先于對象加載進入內(nèi)存的,是隨著類的加載而加載的;this是當前對象的引用,super是指父類的引用,當靜態(tài)方法加載進內(nèi)存進棧時,如果在靜態(tài)方法中有this和super關鍵字時,this和super也被加載到了內(nèi)存,但是這個時候并沒有對象的引用,this和super沒有初始化,所有編譯會報錯。
10.1.子類對象實例化的過程

11.訪問修飾符

public修飾類:
- 一個類中最多只能有一個public類,且文件名要和public類一致
- 如果沒有public類,文件名可以任意
到此這篇關于Java幾個重要的關鍵字詳析的文章就介紹到這了,更多相關Java關鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
關于@Controller和@Restcontroller的那點奇葩事
這篇文章主要介紹了關于@Controller和@Restcontroller的那點奇葩事,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
詳解Java的Struts框架中上傳文件和客戶端驗證的實現(xiàn)
這篇文章主要介紹了Java的Struts框架中上傳文件和客戶端驗證的實現(xiàn),Struts是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12
Java 根據(jù)網(wǎng)址查詢DNS/IP地址的方法
這篇文章主要介紹了Java 根據(jù)網(wǎng)址查詢DNS/IP地址的方法,具體實現(xiàn)代碼,大家參考下本文2017-12-12
java eclipse 整個項目或包查找只定字符串并替換操作
這篇文章主要介紹了java eclipse 整個項目或包查找只定字符串并替換操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
springboot接收前端參數(shù)的四種方式圖文詳解
Spring Boot可以通過多種方式接收前端傳遞的數(shù)據(jù),下面這篇文章主要給大家介紹了關于springboot接收前端參數(shù)的四種方式,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-11-11
Java中Vector與ArrayList的區(qū)別詳解
本篇文章是對Java中Vector與ArrayList的區(qū)別進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Java+MySql圖片數(shù)據(jù)保存與讀取的具體實例
之前一直沒有做過涉及到圖片存儲的應用,最近要做的東東涉及到了這個點,就做了一個小的例子算是對圖片存儲的初試吧2013-06-06

