您好,登錄后才能下訂單哦!
這篇文章主要介紹Java如何使用訪問修飾符,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
訪問修飾符是Java語法中很基礎(chǔ)的一部分,但是能正確的使用Java訪問修飾符的程序員只在少數(shù)。在Java組件開發(fā)中,如果能夠恰到好處的使用訪問修飾符,就能很好的隱藏組件內(nèi)部數(shù)據(jù)和不必公布的實現(xiàn)細(xì)節(jié),從而把組件API和實現(xiàn)細(xì)節(jié)隔離;正確的使用訪問修飾符開發(fā)的Java組件,在組件與組件的調(diào)用和依賴過程中,也能很好的解耦程序,以至于整個組件能夠持續(xù)開發(fā)、持續(xù)測試、持續(xù)更新。
小捌溫馨總結(jié):
通過限制訪問范圍達到信息隱藏或封裝的效果,保證程序?qū)崿F(xiàn)細(xì)節(jié)的安全
解耦組件,使得組件之間的耦合關(guān)系降低,從而能夠低成本、低風(fēng)險(不影響其他組件)的迭代
Java語法提供了四種級別的訪問修飾符,作用于域、方法、類、接口,它們的可訪問性如下所示:
訪問修飾符 | 名稱 | 訪問性 |
---|---|---|
private | 私有的 | 聲明該成員的類才可以訪問。注意:頂層類不能被private和protected修飾,內(nèi)部類可以 |
default/package-private | 包級私有的 | 聲明該成員的類同一包下的任何類均可以訪問 |
protected | 受保護的 | 聲明該成員的類同一包下、子類可以訪問 |
public | 共有的 | 任何地方均可訪問 |
注意:private和default并不是絕對安全,如果類實現(xiàn)了Serializable,這些被private和defaulte修飾的域同一可能被導(dǎo)出;其次反射也是可以跨過訪問修飾符的限制。
Java訪問修飾符使用的原則非常簡單:在實現(xiàn)Java組件的過程中,保證組件功能一致的同時,盡可能讓類、類成員不被外界訪問。
這一條規(guī)則看似非常簡單,但是往往給讓程序員產(chǎn)生一種誤導(dǎo),他把類所有的方法和屬性都不假思索的設(shè)置為private。
這會導(dǎo)致一個什么問題呢?在組件對外公布的時候或者迭代更新的時候,需要不斷的顛覆以前的設(shè)計,把更多的API對外公出來,但是總的來說這也好過把類中所有成員都用public修飾,這種方式是完全不能接收的,兄弟們。
那問題來了,具體應(yīng)該怎么搞呢?
其實小捌覺得只需要明白三個點,因為訪問修飾符作用于類、方法、屬性;所以針對如下三者分析它們應(yīng)該怎么選擇訪問修飾符。
對于類來說有如下規(guī)則:
接口沒得選,默認(rèn)就是public
頂層普通類,我們可以選擇public和default,此時應(yīng)該著重考慮這個頂層類是否只是在當(dāng)前包中提供的抽象,如果滿足這個條件就可以好不由于的設(shè)置為default,但是如果這個頂層類需要被包外其他類直接使用,那就只能設(shè)置為public
非頂層普通類,這種類主要是內(nèi)部類,內(nèi)部類有匿名內(nèi)部類、非匿名內(nèi)部類;匿名內(nèi)部類不考慮;非匿名內(nèi)部類又有靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類,這兩者在選擇訪問修飾符的時候小捌認(rèn)為沒有區(qū)別,盡可能的選擇私有,因為你都將他設(shè)計為內(nèi)部類,說明這個類抽象就是給外層類提供抽象支持的;所以處于組件設(shè)計安全性考慮,盡可能設(shè)計為私有,如果在外部需要使用,可以通過外層類提供API訪問。
對于方法來說有如下規(guī)則:
接口方法沒得選,默認(rèn)public,根據(jù)里氏替換原則,任何使用超類的地方均可以使用子類實例,子類的訪問修飾符必須大于等于超類,所以子類也只有public一種選擇
普通類方法,設(shè)計類之前要先設(shè)計類需要對外公布的API,也就是類需要對外提供那些功能/服務(wù),這個一定要先于寫代碼之前設(shè)計好,之后我們再考慮將這些API設(shè)計為default、protected、public,關(guān)于具體細(xì)節(jié)必須使用private修飾
對于屬性來說有如下規(guī)則:
如果類是共有的,一定不能將實例域公開;因為一旦公開實例域,等于其他類中可以修改這個實例域,無法保證實例域的安全性
如果屬性能夠定義為常量,我們一定要使用static final進行修飾,這樣對外暴露的域具有較高安全性。注意不要在常量域中定義數(shù)組等可變對象。
關(guān)于常量域中定義數(shù)組對象帶來的危險性,小捌做個Demo演示
定義Person對象:
public class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Person{" + "name='" + name + ''' + '}'; } }
定義數(shù)組域所屬類:
public class PersonDemo { public static final Person[] PERSONS = new Person[] {new Person("李子柒"), new Person("李子捌")}; }
測試代碼:
class Test { public static void main(String[] args) { Arrays.stream(PersonDemo.PERSONS).forEach(System.out::println); for (int i = 0; i < PersonDemo.PERSONS.length; i++) { PersonDemo.PERSONS[i] = new Person(PersonDemo.PERSONS[i].getName() + "被修改啦!"); } System.out.println(); Arrays.stream(PersonDemo.PERSONS).forEach(System.out::println); } }
測試結(jié)果可以看出,數(shù)組內(nèi)容被修改了,這往往不是我們定義一個常量時所希望看到的。
關(guān)于這種方式的處理也很簡單,可以將數(shù)組域私有化,并且提供一個API來訪問數(shù)組的拷貝
public class PersonDemo { private static final Person[] PERSONS = new Person[] {new Person("李子柒"), new Person("李子捌")}; public static final Person[] getPersons() { return PERSONS.clone(); } }
此時外部無法直接訪問PERSONS數(shù)組,訪問的只是數(shù)組的拷貝,修改的也只是數(shù)組的拷貝,無法修改到數(shù)組域的內(nèi)容。
此外也可以使用Collections工具類將其包裝為不可變集合,包裝成UnmodifiableCollection對象之后,set、add、remove等方法調(diào)用會拋出UnsupportedOperationException:
public class PersonDemo { private static final Person[] PERSONS = new Person[] {new Person("李子柒"), new Person("李子捌")}; public static final List<Person> getPersons() { return Collections.unmodifiableList(Arrays.asList(PERSONS)); } }
以上是“Java如何使用訪問修飾符”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。