java的特點
- 面對對象編程(OOP):封裝,繼承,多態(tài)。
https://www.cnblogs.com/chenssy/p/3372798.html
https://www.cnblogs.com/crane-practice/p/3671074.html
什么是多態(tài)?多態(tài)的實現(xiàn)機制是什么?
- 多態(tài)分為編譯時多態(tài)和運行時多態(tài),編譯時多態(tài)指的時方法的重載,即方法名相同,參數(shù)不同;運行時多態(tài)指的是方法的重寫。
運行時多態(tài):父類引用指向子類對象,并調(diào)用子類的重寫方法。 - 多態(tài)實現(xiàn)的機制是什么呢?
其實就是依靠靜態(tài)分派和動態(tài)分派。
靜態(tài)分派即在編譯期間就能完全確定,在類加載的解析階段就會把所涉及的符號引用轉(zhuǎn)化為可確定的直接引用,不會延遲到運行期再去完成,典型的例子就是方法重載。
動態(tài)分派是指在運行期間才能確定變量的實際類型,典型的例子就是方法的重寫。只有在運行期間,根據(jù)對實例化子類的不同,調(diào)用不同子類中重寫的方法。
https://blog.csdn.net/ns_code/article/details/17965867
https://blog.csdn.net/sunxianghuang/article/details/52280002
靜態(tài)屬性和靜態(tài)方法是否可以被繼承?是否可以被重寫?以及原因?
不存在靜態(tài)方法的重寫,當一個子類繼承父類時,寫同樣的方法時,只是將父類的靜態(tài)方法隱藏。
理由:靜態(tài)方法對應(yīng)的invokestatic,它所需要的符號引用在類加載階段符號引用解析成為直接引用了,靜態(tài)分派。
https://blog.csdn.net/dawn_after_dark/article/details/74357049
https://blog.csdn.net/TyroneRenekton/article/details/68923475
==、equals、hashCode
1 、== 對于基本類型來說,比較的是值是否相等;對于引用類型來說,比較的是是否同一個對象。對象是放在堆中的,棧中存放的是對象的引用(地址)。由此可見'=='是對棧中的值進行比較的。
2、equal 是Object中的方法,等效于"==",比較是否是同一個對象;String類復(fù)寫了Object的equal方法,比較的是對象的內(nèi)容。
3、hashCode是Object中的方法,返回一個int類型的hash碼,大概可以認為是對象的內(nèi)存地址。
4、equal()和hashCode()作用一樣,都是比較是否是同一個對象,那么比較對象是否相同時只用equal()或者只用hashCode()不就行了,為什么要一起用?
理由:equal比較效率太低,hashCode比較不完全可靠,所以需要結(jié)合起來。
詳細解釋:
(1)重寫的equal()里一般比較的比較全面比較復(fù)雜,這樣效率就比較低,而利用hashCode()進行對比,則只要生成一個hash值進行比較就可以了,效率很高。
(2)Java中的集合(Collection)有兩類,一類是List,再有一類是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素無序,但元素不可重復(fù)。
那么這里就有一個比較嚴重的問題了:要想保證元素不重復(fù),可兩個元素是否重復(fù)應(yīng)該依據(jù)什么來判斷呢?
這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那么當元素很多時,后添加到集合中的元素比較的次數(shù)就非常多了。也就是說,如果集合中現(xiàn)在已經(jīng)有1000個元素,那么第1001個元素加入集合時,它就要調(diào)用1000次equals方法。這顯然會大大降低效率。
(3)hashCode()并不是完全可靠,有時候不同的對象他們生成的hashcode也會一樣(生成hash值得公式可能存在的問題),所以hashCode()只能說是大部分時候可靠,并不是絕對可靠,所以我們可以得出:equal()相等的兩個對象他們的hashCode()肯定相等,也就是用equal()對比是絕對可靠的;hashCode()相等的兩個對象他們的equal()不一定相等,也就是hashCode()不是絕對可靠的。
(4)所以,對于需要大量并且快速的對比的話如果都用equal()去做顯然效率太低,所以解決方式是,每當需要對比的時候,首先用hashCode()去對比,如果hashCode()不一樣,則表示這兩個對象肯定不相等(也就是不必再用equal()去再對比了),如果hashCode()相同,此時再對比他們的equal(),如果equal()也相同,則表示這兩個對象是真的相同了,這樣既能大大提高了效率也保證了對比的絕對正確性!
https://www.cnblogs.com/kexianting/p/8508207.html
https://www.cnblogs.com/keyi/p/7119825.html
String 相關(guān)
- new String("a")創(chuàng)建了幾個對象
答案:1個或者2個
new一個字符串時,做了兩件事。首先在堆中生成了該字符串對象,然后去看常量池中有沒有該字符串,如果有就不管了,沒有就往常量池中添加一個。
http://www.itdecent.cn/p/d416a074409d - String 為什么設(shè)計為不可變對象
- String StringBuffer和StringBuilder的比較:拼接效率、線程安全
str += "c";相當于str = new StringBuilder(str).append("JTZen9").toString();
多了創(chuàng)建StringBuilder對象和toString()方法
https://blog.csdn.net/m0_37589327/article/details/78605268
https://www.cnblogs.com/zyh1994/p/5845632.html
淺拷貝與深拷貝
淺拷貝實現(xiàn)了基本類型的復(fù)制,引用類型只拷貝了引用,即2個對象中引用指向同一個對象。
https://www.cnblogs.com/Qian123/p/5710533.html#_label3
final、finally、finally
- final:可以修飾變量,方法,類; 修飾變量時表明這對象的值不可變,你不能為這個變量賦一個新的值,或者這樣說:對基本類型而言,你不能改變其數(shù)值,對于引用,你不能將其指向一個新的引用(而引用自身是可以改變的)。 修飾方法時表明我們希望把這個方法鎖定,以防止任何繼承類修改它的含義,這樣會確保在繼承中,我們的 final 方法的行為不會改變,并且不會被覆蓋。使用 final 方法的另一個考慮是效率問題:在 Java 早期的時候,遇到 final 方法,編譯器會將此方法調(diào)用轉(zhuǎn)為內(nèi)嵌調(diào)用,如此一來以減小方法調(diào)用產(chǎn)生的開銷。 修飾類的時候表明你不打算繼承該類,而且也不允許別人這樣做。
finally: 是異常處理中進行收場處理的代碼塊,比如關(guān)閉一個數(shù)據(jù)庫連接,清理一些資源占用的問題。不管有沒有異常被捕獲,finally 子句中的代碼都會被執(zhí)行。
finalize: finalize 出現(xiàn)的原因在于,我們一定需要進行清理動作。Java 沒有用于釋放對象的,如同 C++ 里的 delete 調(diào)用,的方法,而是使用垃圾回收器(GC)幫助我們釋放空間。當垃圾回收器準備釋放對象占用的存儲空間的時候,將首先調(diào)用其 finalize() 方法。
抽象類與接口的異同
String是值傳遞還是應(yīng)用傳遞
https://blog.csdn.net/party3/article/details/78648186
https://www.cnblogs.com/boboooo/p/9066831.html