淺析Java中的訪問控制權(quán)限
Java中為什么要設(shè)計(jì)訪問權(quán)限控制機(jī)制呢?主要作用有兩點(diǎn):
(1)為了使用戶不要觸碰那些他們不該觸碰的部分,這些部分對(duì)于類內(nèi)部的操作時(shí)必要的,但是它并不屬于客戶端程序員所需接口的一部分。
(2)為了讓類庫(kù)設(shè)計(jì)者可用更改類的內(nèi)部工作方式,而不必?fù)?dān)心會(huì)對(duì)用戶造成重大影響。
Java中的訪問權(quán)限控制的等級(jí),按照權(quán)限從大到小依次為:
Public -> protected -> 包訪問權(quán)限(沒有權(quán)限修飾詞)-> private。
一、包(package)
Java中包(package)的概念和C++中命名空間(namespace)的概念很類似,都可以限制類的作用域。二者最大的差別在于,Java中的包隱式地指明了類的樹形層級(jí)結(jié)構(gòu)(同時(shí)也是Java源碼文件的目錄結(jié)構(gòu))。這樣做的好處在于:可以通過文件系統(tǒng)中對(duì)于文件路徑唯一性的要求來限制類的唯一性。
1、代碼組織
編寫一個(gè)Java源代碼文件(.java文件)時(shí),此文件通常被稱為編譯單元。在編譯單元內(nèi)最多允許有一個(gè)public類,且該類的名稱必須與文件名完全相同(包括大小寫)。
編譯一個(gè).java文件時(shí),在.java文件中的每個(gè)類都會(huì)有一個(gè).class輸出文件,這個(gè)文件名和類名是相同的。Java可運(yùn)行程序是一組可以打包并壓縮為一個(gè)Java文檔文件(JAR包,使用Java的jar文檔生成器)的.class文件。Java解釋器負(fù)責(zé)這些文件的查找、裝載和解釋。
類庫(kù)實(shí)際上是一組類文件。其中每個(gè).java文件最多允許有一個(gè)public類,以及任意數(shù)量的非public類。因此,每個(gè)文件都有一個(gè)構(gòu)件。如果要將這些構(gòu)件(每個(gè)構(gòu)建有一個(gè).java文件和若干個(gè).class文件)組織起來,形成不同的群組,可以使用Java中的關(guān)鍵字package。
2、包(package)的作用
(1) 把功能相似或相關(guān)的類或接口組織在同一個(gè)包中,方便類的查找和使用。
(2) 如同文件夾一樣,包也采用了樹形目錄的存儲(chǔ)方式。同一個(gè)包中的類名字是不同的,不同的包中的類的名字是可以相同的,當(dāng)同時(shí)調(diào)用兩個(gè)不同包中相同類名的類時(shí),應(yīng)該加上包名加以區(qū)別。因此,包可以避免名字沖突。
(3) 包也限定了訪問權(quán)限,擁有包訪問權(quán)限的類才能訪問某個(gè)包中的類。
3、創(chuàng)建包
Java中,使用package關(guān)鍵字來指定代碼所屬的包(命名空間)。
語(yǔ)法格式:
package pkg1[.pkg2[.pkg3…]];
注意點(diǎn):
(1) 包的名字隱含地指出了代碼的目錄結(jié)構(gòu)。
(2) 同一目錄下的public類名(同時(shí)也是java文件名)應(yīng)該是獨(dú)一無二的。
(3) 包聲明應(yīng)該在源文件的第一行,每個(gè)源文件只能有一個(gè)包聲明,這個(gè)文件中的每個(gè)類型都應(yīng)用于它。
(4) 如果一個(gè)源文件中沒有使用包聲明,那么其中的類,函數(shù),枚舉,注釋等將被放在一個(gè)無名的包(unnamed package)中。
(5) package的名字一般全是小寫字母。
例如:
查看java.util.ArrayList類的源碼可以看到文件第一行代碼為:
package java.util;
它的代碼目錄結(jié)構(gòu)就是java/util/ArrayList.java
4、導(dǎo)入包
Java中,使用import關(guān)鍵字來導(dǎo)入包。
語(yǔ)法格式:
import package1[.package2…].(classname|*);
例:
還是以java.util.ArrayList來舉例。如果以一個(gè)了類完整路徑的方式來使用它,十分不方便。
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
如果想要省略前面的路徑,可以使用import關(guān)鍵字。
import java.util.ArrayList;
文件中使用了import導(dǎo)入包后,前面的聲明list的代碼就可以簡(jiǎn)化如下:
ArrayList<String> list = new ArrayList<String>();
二、訪問權(quán)限修飾詞
1、package:包訪問權(quán)限
如果不提供任何訪問權(quán)限修飾詞,則意味著它是包訪問權(quán)限。
默認(rèn)訪問權(quán)限沒有任何關(guān)鍵字,但通常是指包訪問權(quán)限(有時(shí)也表示為friendly,有點(diǎn)像C++中的友元概念)。這意味著包中所有其他類都可以訪問這個(gè)成員或方法,但是這個(gè)包之外的所有類不可以訪問。
例:
com.notes.packages.test.Info
package com.notes.packages.test;
publicclass Info {
void print() { System.out.println("default method -- print()"); }
}
com.notes.packages.test.PublicDemo01
package com.notes.packages.test;
publicclass PublicDemo01 {
publicstaticvoid main(String[] args) {
Info x = new Info();
x.print();
}
}
PublicDemo01和Info在同一個(gè)包下,可以訪問Info的default級(jí)別的方法——print()。
com.notes.packages.PublicDemo02
package com.notes.packages;
import com.notes.packages.test.Info;
publicclass PublicDemo02 {
publicstaticvoid main(String[] args) {
Info x = new Info();
// x.print(); // Error
}
}
PublicDemo02和Info不在一個(gè)包下,不可以訪問Info的包訪問權(quán)限級(jí)別的方法——print()。
2、public:接口訪問權(quán)限
使用public關(guān)鍵字,就意味著被聲明的成員或方法對(duì)所有人都是可以訪問的。
例:如果將default級(jí)別權(quán)限例子中的print()方法權(quán)限設(shè)為public,則PublicDemo02可以訪問。
package com.notes.packages.test;
publicclass Info {
publicvoid print() { System.out.println("public method -- print()"); }
}
3、private:無法訪問
使用private關(guān)鍵字,就意味著被聲明的成員或方法,除了本類,其他任何類都無法訪問。
應(yīng)用場(chǎng)景:?jiǎn)卫J?/p>
4、protected:繼承訪問權(quán)限
新類(稱之子類或派生類)通過繼承可以復(fù)用一個(gè)現(xiàn)有類(稱之父類或基類),然后擴(kuò)展基類的成員、方法。有時(shí),基類的創(chuàng)建者會(huì)希望某個(gè)特定成員,將它的訪問權(quán)限賦予派生類而不是所有類。public無法做到這一點(diǎn),為此,引入了protected來完成這一工作。protected也提供包訪問權(quán)限,也就是說,派生類以及相同包內(nèi)的其他類都可以訪問protected成員或方法。
例:子類繼承父類后,可以訪問父類的protected成員。
class Father {
private String a = "private";
protected String b = "protected";
public String c = "public";
};
class Son extends Father {
publicvoid print() {
// System.out.println("element a:" + super.a); // Error
System.out.println("element b:" + super.b);
System.out.println("element c:" + super.c);
}
}
publicclass ProtectedDemo01 {
publicstaticvoid main(String args[]) {
Son sub = new Son();
sub.print();
}
};
訪問權(quán)限修飾詞的注意點(diǎn)
前面各個(gè)例子中展示了類的成員、方法都可以用各種權(quán)限修飾詞來修飾。
除此之外,還有一些需要注意的點(diǎn):
(1) 靜態(tài)成員、靜態(tài)方法的權(quán)限修飾詞的用法和普通成員、方法一樣。
(2) 類雖然也可以被修飾詞修飾,但是不可以用private、protected兩個(gè)權(quán)限修辭詞。
(3) 有些書中將包訪問權(quán)限又叫做默認(rèn)訪問權(quán)限。個(gè)人不建議這么去記,因?yàn)檫@很容易與Java Se8中新特性——default關(guān)鍵字混淆。這個(gè)關(guān)鍵字只能用于Interface,作用是允許程序員在Interface中定義接口的默認(rèn)具體實(shí)現(xiàn)(以往的JDK版本是不允許這樣的,你只能在接口中聲明方法)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之醫(yī)院心理咨詢問診系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+Spring+Maven+mybatis+Vue+mysql開發(fā)的醫(yī)院心理咨詢問診系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有心理咨詢問診該有的所有功能,感興趣的朋友快來看看吧2022-01-01
SpringBoot 攔截器和自定義注解判斷請(qǐng)求是否合法
這篇文章主要介紹了SpringBoot 攔截器和自定義注解判斷請(qǐng)求是否合法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下2020-12-12
Java中List.contains(Object?object)方法使用
本文主要介紹了Java中List.contains(Object?object)方法,使用List.contains(Object?object)方法判斷ArrayList是否包含一個(gè)元素對(duì)象,感興趣的可以了解一下2022-04-04
java中BeanUtils.copyProperties的用法(超詳細(xì))
本文介紹了BeanUtils.copyProperties()方法的使用,包括其功能、用法、注意事項(xiàng)和示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
IntelliJ IDEA優(yōu)化配置的實(shí)現(xiàn)
這篇文章主要介紹了IntelliJ IDEA優(yōu)化配置的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
springboot?jpa?實(shí)現(xiàn)返回結(jié)果自定義查詢
這篇文章主要介紹了springboot?jpa?實(shí)現(xiàn)返回結(jié)果自定義查詢方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Spring Kafka中@KafkaListener注解的參數(shù)與使用小結(jié)
@KafkaListener注解為開發(fā)者提供了一種聲明式的方式來定義消息監(jiān)聽器,本文主要介紹了Spring Kafka中@KafkaListener注解的參數(shù)與使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06

