jdk中String類設(shè)計(jì)成final的原由
更新時(shí)間:2013年01月03日 11:40:31 作者:
為什么jdk中把 String 類設(shè)計(jì)成final,主要是為了“ 效率 ”和“安全性”的緣故,若 String 允許被繼承, 由于它的高度被使用率, 可能會降低程序的性能,所以String被定義成final,需要了解的朋友可以參考下
最佳答案:
主要是為了 “ 效率 ” 和 “ 安全性 ” 的緣故。 若 String 允許被繼承, 由于它的高度被使用率, 可能會降低程序的性能,所以 String 被定義成 final。
其它答案一:
String 和其他基本類型不同 , 他是個(gè)對象類型. 既然是對象類型 , 如果是在靜態(tài)方法下是必須調(diào)用靜態(tài)方法或值的 , 如果是非靜態(tài)的方法 , 就必須要實(shí)例化.
main 函數(shù)是個(gè) static 的. 所以 String 要能像其他的基本類型一樣直接被調(diào)用. 這也是為什么在 main 函數(shù)下使用 String 類型不會報(bào)告錯(cuò)誤的原因..
一下就解釋了兩個(gè)心里的疑問..
以前一直覺得奇怪 , 為什么 String 是對象類型在 main 函數(shù)下卻是不需要實(shí)例化的. 再次佩服 java 設(shè)計(jì)人員想得真周到.
其它答案二:
當(dāng)定義 String 類型的靜態(tài)字段(也成類字段),可以用靜態(tài)變量(非 final)代替常量(final)加快程序速度。 反之,對于原始數(shù)據(jù)類型,例如 int,也成立。
例如,你可能創(chuàng)建一個(gè)如下的 String 對象:
private static final String x = "example";
對于這個(gè)靜態(tài)常量(由 final 關(guān)鍵字標(biāo)識),你使用常量的每個(gè)時(shí)候都會創(chuàng)建一個(gè)臨時(shí)的 String 對象。 在字節(jié)代碼中,編譯器去掉 ”x”,代替它的是字符串 “example”, 以致每次引用 ”x” 時(shí) VM 都會進(jìn)行一次哈希表查詢。
相比之下,度于靜態(tài)變量 ( 非 final 關(guān)鍵字 ),字符串只創(chuàng)建一次。 僅當(dāng)初始化 “x” 時(shí), VM 才進(jìn)行哈希表查詢。
還有另一個(gè)解釋:
帶有 final 修飾符的類是不可派生的。 在 java 核心 API 中,有許多應(yīng)用 final 的例子,例如 java.lang.String。 為 String 類指定 final 防止了人們覆蓋 length() 方法。
另外,如果指定一個(gè)類為 final,則該類所有的方法都是 final。 java 編譯器會尋找機(jī)會內(nèi)聯(lián)(inline)所有的 final 方法(這和具體的編譯器實(shí)現(xiàn)有關(guān))。 此舉能夠使性能平均提高 50%。
示例:
public class Test {
public static void main(String[] args) {
//
}
}
如果 String 不是 final 那么就可以繼承
public class String2 extends String{
//..
//...
}
那我們的 main 也就可以寫成
public class Test {
public static void main(String2[] args) { // 注意此處
//
}
}
另外補(bǔ)充一點(diǎn):
作用就是 final的類不能被繼承,不能讓別人繼承有什么好處?
意義就在于,安全性,如此這般:
java 自出生那天起就是“為人民服務(wù)”,這也就是為什么java做不了病毒,也不一定非得是病毒,反正總之就是為了安全, 人家java的開發(fā)者目的就是不想讓 java干這類危險(xiǎn)的事兒,java并不是操作系統(tǒng)本地語言, 換句話說java必須借助操作系統(tǒng)本身的力量才能做事,JDK中提供的好多核心類比如 String,這類的類的內(nèi)部好多方法的實(shí)現(xiàn)都不是java編程語言本身編寫的, 好多方法都是調(diào)用的操作系統(tǒng)本地的API,這就是著名的“本地方法調(diào)用”,也只有這樣才能做事,這種類是非常底層的, 和操作系統(tǒng)交流頻繁的,那么如果這種類可以被繼承的話,如果我們再把它的方法重寫了,往操作系統(tǒng)內(nèi)部寫入一段具有惡意攻擊性質(zhì)的代碼什么的, 這不就成了核心病毒了么?
上面所述是最重要的,另外一個(gè)方面,上面2位老兄說的也都很對, 就是不希望別人改,這個(gè)類就像一個(gè)工具一樣,類的提供者給我們提供了, 就希望我們直接用就完了,不想讓我們隨便能改,其實(shí)說白了還是安全性, 如果隨便能改了,那么java編寫的程序肯定就很不穩(wěn)定,你可以保證自己不亂改, 但是將來一個(gè)項(xiàng)目好多人來做,管不了別人,再說有時(shí)候萬一疏忽了呢?他也不是估計(jì)的, 所以這個(gè)安全性是很重要的,java和C++相比,優(yōu)點(diǎn)之一就包括這一點(diǎn);
原因絕對不只有這么多,因?yàn)槿绻@些個(gè)核心的類都能被隨便操作的話,那是很恐怖的,會出現(xiàn)好多好多未知的錯(cuò)誤,莫名其妙的錯(cuò)誤….
主要是為了 “ 效率 ” 和 “ 安全性 ” 的緣故。 若 String 允許被繼承, 由于它的高度被使用率, 可能會降低程序的性能,所以 String 被定義成 final。
其它答案一:
String 和其他基本類型不同 , 他是個(gè)對象類型. 既然是對象類型 , 如果是在靜態(tài)方法下是必須調(diào)用靜態(tài)方法或值的 , 如果是非靜態(tài)的方法 , 就必須要實(shí)例化.
main 函數(shù)是個(gè) static 的. 所以 String 要能像其他的基本類型一樣直接被調(diào)用. 這也是為什么在 main 函數(shù)下使用 String 類型不會報(bào)告錯(cuò)誤的原因..
一下就解釋了兩個(gè)心里的疑問..
以前一直覺得奇怪 , 為什么 String 是對象類型在 main 函數(shù)下卻是不需要實(shí)例化的. 再次佩服 java 設(shè)計(jì)人員想得真周到.
其它答案二:
當(dāng)定義 String 類型的靜態(tài)字段(也成類字段),可以用靜態(tài)變量(非 final)代替常量(final)加快程序速度。 反之,對于原始數(shù)據(jù)類型,例如 int,也成立。
例如,你可能創(chuàng)建一個(gè)如下的 String 對象:
復(fù)制代碼 代碼如下:
private static final String x = "example";
對于這個(gè)靜態(tài)常量(由 final 關(guān)鍵字標(biāo)識),你使用常量的每個(gè)時(shí)候都會創(chuàng)建一個(gè)臨時(shí)的 String 對象。 在字節(jié)代碼中,編譯器去掉 ”x”,代替它的是字符串 “example”, 以致每次引用 ”x” 時(shí) VM 都會進(jìn)行一次哈希表查詢。
相比之下,度于靜態(tài)變量 ( 非 final 關(guān)鍵字 ),字符串只創(chuàng)建一次。 僅當(dāng)初始化 “x” 時(shí), VM 才進(jìn)行哈希表查詢。
還有另一個(gè)解釋:
帶有 final 修飾符的類是不可派生的。 在 java 核心 API 中,有許多應(yīng)用 final 的例子,例如 java.lang.String。 為 String 類指定 final 防止了人們覆蓋 length() 方法。
另外,如果指定一個(gè)類為 final,則該類所有的方法都是 final。 java 編譯器會尋找機(jī)會內(nèi)聯(lián)(inline)所有的 final 方法(這和具體的編譯器實(shí)現(xiàn)有關(guān))。 此舉能夠使性能平均提高 50%。
示例:
復(fù)制代碼 代碼如下:
public class Test {
public static void main(String[] args) {
//
}
}
如果 String 不是 final 那么就可以繼承
復(fù)制代碼 代碼如下:
public class String2 extends String{
//..
//...
}
那我們的 main 也就可以寫成
復(fù)制代碼 代碼如下:
public class Test {
public static void main(String2[] args) { // 注意此處
//
}
}
另外補(bǔ)充一點(diǎn):
作用就是 final的類不能被繼承,不能讓別人繼承有什么好處?
意義就在于,安全性,如此這般:
java 自出生那天起就是“為人民服務(wù)”,這也就是為什么java做不了病毒,也不一定非得是病毒,反正總之就是為了安全, 人家java的開發(fā)者目的就是不想讓 java干這類危險(xiǎn)的事兒,java并不是操作系統(tǒng)本地語言, 換句話說java必須借助操作系統(tǒng)本身的力量才能做事,JDK中提供的好多核心類比如 String,這類的類的內(nèi)部好多方法的實(shí)現(xiàn)都不是java編程語言本身編寫的, 好多方法都是調(diào)用的操作系統(tǒng)本地的API,這就是著名的“本地方法調(diào)用”,也只有這樣才能做事,這種類是非常底層的, 和操作系統(tǒng)交流頻繁的,那么如果這種類可以被繼承的話,如果我們再把它的方法重寫了,往操作系統(tǒng)內(nèi)部寫入一段具有惡意攻擊性質(zhì)的代碼什么的, 這不就成了核心病毒了么?
上面所述是最重要的,另外一個(gè)方面,上面2位老兄說的也都很對, 就是不希望別人改,這個(gè)類就像一個(gè)工具一樣,類的提供者給我們提供了, 就希望我們直接用就完了,不想讓我們隨便能改,其實(shí)說白了還是安全性, 如果隨便能改了,那么java編寫的程序肯定就很不穩(wěn)定,你可以保證自己不亂改, 但是將來一個(gè)項(xiàng)目好多人來做,管不了別人,再說有時(shí)候萬一疏忽了呢?他也不是估計(jì)的, 所以這個(gè)安全性是很重要的,java和C++相比,優(yōu)點(diǎn)之一就包括這一點(diǎn);
原因絕對不只有這么多,因?yàn)槿绻@些個(gè)核心的類都能被隨便操作的話,那是很恐怖的,會出現(xiàn)好多好多未知的錯(cuò)誤,莫名其妙的錯(cuò)誤….
相關(guān)文章
Spring Security 安全框架應(yīng)用原理解析
這篇文章主要介紹了Spring Security 安全框架應(yīng)用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07SpringCloud Zuul過濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例
這篇文章主要介紹了SpringCloud Zuul過濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03詳解Spring boot Admin 使用eureka監(jiān)控服務(wù)
本篇文章主要介紹了詳解Spring boot Admin 使用eureka監(jiān)控服務(wù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12SpringBoot通過@Value實(shí)現(xiàn)給靜態(tài)變量注入值詳解
這篇文章主要介紹了springboot如何通過@Value給靜態(tài)變量注入值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Java Collections集合繼承結(jié)構(gòu)圖_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java Collections集合繼承結(jié)構(gòu)圖_動力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-04-04