複習總結

short char byte 參與運算會默認轉換成int類型;
short s=1;
short s=(short)s+1;  解決方法:強制類型轉換;
                                                                                  

字符串+(字符串拼接符)任何數據=字符串
舉例:System.out.println("5+5="+5+5); //"5+5=55"
                                                                                  

switch語句中:恰當使用 case穿透;
                                                                                                                                                        

while循環和for循環的區別:
1)如果從內存角度考慮:
for循環要優於while循環,for循環語句執行完畢之後,變量會及時被GC垃圾回收期回收掉
while循環,它可以去訪問循環語句中的變量
  2)根據具體需求具體分析:
  如果循環次數明確的情況下,應用for循環  
  如果不知道要循環多少次,應該去使用while循環
                                                                                   

使用數組時小心下標越界:ArrayIndexOutOfBoundsException:數組角標越界異常
解決方案:觀察數組中到底有索引值到多少;  數組長度-1
                                                                                  

面向對象思想的特徵:
1)面向對象更符合我們的生活中的行爲思想習慣
2)面向對象將我們從執行者變成了指揮者,指揮對象做事情
3)面向對象簡單性體現在這裏:讓我們做的事情從複雜性--->簡單化
                                                                                  

關於static關鍵字:
  1)靜態隨着類的加載而加載
  2)static優先於對象存在
  回想:main  public static void main(..){...}
  3)static共享數據,可以被多個對象進行共享
  舉例: 飲水機(staticd的:共享的)
  水杯(不能共享的...)
  4)如果數據被靜態修飾的,它可以被類名直接調用
  被靜態修飾的方法: 類名.方法名()
  被靜態修飾的變量: 類名.變量名;
                                                                                   


關於代碼塊的概述:
用{}括起來的代碼,統稱爲代碼塊;
根據其位置以及聲明不同:分爲以下:
局部代碼塊:在main()裏面,給變量限定它的生命週期;
構造代碼塊:在一個類中的成員位置中,用{}括起來;
作用:可以將多個構造方法中的相同的代碼放到構造代碼塊中,對對象進行初始化.    在每次執行構造方法
                                  之前,先執行構造代碼塊;
靜態代碼塊:在一個類的成員位置,也是用{}包起來,但是他被static修飾;
作用:一般情況 它的作用給類進行初始化;

                                                                                   

成員變量(類)和局部變量(方法)的區別:
  1)在類中位置不同
  成員變量:類中,方法外;
  局部變量:方法聲明上,或者再方法定義中;
  2)在內存中的位置不同
  成員變量:堆內存;
  局部變量:棧內存;
  3)生命週期不同
  成員變量:成員變量是隨着類的加載而加載,隨着類的消失而消失;
  局部變量:隨着方法的調用而存在,隨着方法調用完畢而消失;
  4)初始化值不同
  成員變量:初始化由系統默認初始化,對於成員變量,可以不給初始化值,由系統給,然後顯示初始化;
  局部變量:定義一個局部變量,必須進行初始化,如果不初始化,無法使用(在使用之前進行初始化) ;
                                                                                   

this:代表是當前類對象,或者是(當前類對象的引用),解決局部隱藏了成員變量
                                                                                   

多態的前提:
  1)必須有繼承關係
  子類繼承父類,存在一些特點
  2)必須有方法重寫
  子類繼承父類,方法重寫的目的,舉例:動物吃的方法,每一個具體動物吃的東西不一樣,所有必須要方法覆蓋
  3)就是必須有父類的引用指向子類對象 (向上轉型)
  父類名  fu = new  子類名() ;  (父類的引用指向子類對象)
                                                                                   

多態中的成員訪問特點:
1)成員變量: 編譯看左,運行看左...
2)成員方法(非靜態): 編譯看左,運行看右(存在方法重寫)
3)構造方法:構造方法(無論子類,還是父類),都是對對象進行初始化
4)靜態成員方法:    編譯看左,運行看左(靜態跟類有關係,算不上方法重寫)
                                                                                   

要點:多態中,訪問父類子類都有的非靜態方法,那麼運行結果看子類;
   訪問父類子類都有的靜態方法,那麼運行結果看父類;
   多態的前提之一有,方法重寫,那麼不能訪問子類的特有的方法;

                                                                                   

多態的好處:
可以提供代碼的複用性:繼承保證
可以提高的代碼的擴展性:由多態保證
                                                                                   

多態的弊端:通過父類的引用調用子類特有功能,不能調用
  解決:將父類的引用強制轉換子類的引用 (訪問子類的特有功能)
  舉例:Father3 f  = new Son3() ;//向上轉型
Son3 s = (Son3) f ; //前提是必須有父類的引用
                                                                                   

將父類的引用強制轉換子類的引用  ,向下轉型使用不當,會出現一個異常:屬於運行時期異常:ClassCastException
                                                                                   

this和super關鍵字的用法:
  成員變量:
  this:this.成員變量; (訪問當前類)
  super:super.成員變量;(訪問父類)
  構造方法:
  this(); //無參構造
  this("") ;//訪問當前類的有參構造
  super()://訪問的父類的無參構造
  super("")://訪問的是父類的有參構造..
  成員方法:
  this.xx()
  super.xx()
                                                                                  

關於this和super的區別?
this:代表當前類的對象
super:代表父類空間標識,理解爲代表父類的對象
成員變量
this.成員變量
super.成員變量
成員方法
this.成員方法()
super.成員方法();
構造方法
this()/this("..")
super()/super("...");
                                                                                  

 當子類中的成員方名和父類中的成員方法名一致的情況:
1)現在子類的成員位置找,如果有就調用
  2)如果沒有找到,在父類的成員位置找,有就調用
                                                                                  

關於代碼塊的概述:用{}括起來的代碼,統稱爲代碼塊;
  根據其位置以及聲明不同:分爲以下:
  局部代碼塊: 在main()裏面,給變量限定它的生命週期
  構造代碼塊:在一個類中的成員位置中,用{}括起來,
  作用:可以將多個構造方法中的相同的代碼放到構造代碼塊中,對對象進行初始化.    在每次執行構造方法之前,先執行構造代碼塊.
  靜態代碼塊:在一個類的成員位置,也是用{}包起來,但是他被static修飾
  作用:一般情況 它的作用給類進行初始化
                                                                                  

構造代碼塊,構造方法,靜態代碼的優先級?
答案:靜態代碼塊>構造代碼塊>構造方法
靜態代碼:只能執行一次
構造代碼塊在每次執行構造方法之前都會被執行
                                                                                  

overload和override的區別?
overload:方法重載(方法名一樣,參數不同,和返回值沒有關係)
參數不同:
1)參數個數不同
2)參數類型不同
override:方法重寫 (子類定義一個和父類一摸一樣的方法聲明)
                                                                                  

接口:體現的是事務的擴展性功能(額外動作,後天經過學習等等)
                                                                                  

接口成員的特點:
  成員變量:是一個常量,不能更改,並且默認的修飾符
  public static final:
  構造方法:接口不存在構造方法
成員方法:都是抽象方法
默認的修飾符:public abstract
                                                                                 

接口和接口之間的關係:繼承關係;
類和類之間的關係:繼承關係
類和接口之間的關係:實現關係
                                                                                  


靜態成員內部類訪問外部類的數據,該數據必須static修飾
        內部類被static修飾 ==> Outer.Inner oi=new Outer.Inner();

                                                                                  

多態(方法重寫):父類和子類都有方法實現;
抽象類(abstract):子類必須實現父類中的抽象方法,並且子類不能是抽象類,沒有意義(不能實例化);
                                                                                  

接口和抽象類的區別:
A)成員的區別:
成員變量:
抽象類:既可以常量,也可以是變量
接口:只能是常量,默認的修飾符:public static final
構造方法:
抽象類:有構造方法,無參/有參 (給對象進行初始化的)
接口:沒有構造方法
成員方法:
抽象類:可以有抽象方法,也可以有非抽象方法
接口:只能是抽象方法 :默認的修飾符:public abstract
B)類與類/類與接口關係的區別:
類與類之間的關係:
繼承關係,只支持單繼承,不支持多繼承,但是可以多層繼承
類與接口的關係:
實現關係,一個類繼承另一個類的同時,還可以實現多個接口...
接口與接口的關係:
是一種繼承關係,既可以單繼承,也可以多繼承...
接口1 extends 接口2,接口3...
C)設計原則的 區別
1)抽象類: 是有繼承關係---->體現的是一種"is a"的關係   (A是B的一種或者B是A的一種)
2)接口:類和接口:實現關係--->體現的是一種" like a"的關係(擴展功能)  :跳高貓 像貓
                                                                                  

匿名內部類的本質:
是繼承了該類或者實現了該接口子類對象
                                                                                  

Object:是類層次結構的根類.每個類都使用 Object 作爲超類(父類)
                                                                                  

鍵盤輸入數據:先輸入int類型,再輸入String類型,會有問題;
        解決:重新創建一個鍵盤輸入對象
                                                                                  

String最大的特點:字符串一旦被賦值,其值不能改變;
  原因:直接把一個常量賦值給String類型,這種形式,它是在方法去中的字符串常量池中看有沒有當前字符串,有直接返回它的地址,沒有就在常量池中開闢空間;
                                                                                  

StringBuffer和String的區別?
前者是一個可變的字符序列,後者是不可變的字符序列
如果從內存角度考慮,String定義的時候,會在常量池中開闢空間,比較耗費內存
而StringBuffer,字符串緩衝區(裏面存儲的全部都是字符串),它會釋放掉
                                                                                  

StringBuffer,String,StringBuilder的區別?
StringBuffer和StringBuilder都是一個可變的字符序列,提供一個緩衝區.(兩者都看做容器)
StringBuffer:線程安全的,同步的,執行效率低
StringBuilder:線程不安全的,不同步的,執行效率高,並且單線程中優先採用StringBuilder
StringBuffer 執行效率雖然低,但是優於String類型,並且他是一個可變的字符序列,提供了緩衝區

                                                                                  

StringBuffer和數組的區別?
數組:它是可以存儲多個數據的容器,並且多個數據的類型必須一致
數組長度功能:length屬性
StringBuffer:它是容器,它在緩衝區始終存儲的只能字符串類型的數據
獲取緩衝區的長度:length() 
                                                                                  

Calendar 類是一個抽象類(不能實例化),它爲特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日曆字段之間的轉換提供了一些方法,併爲操作日曆字段(例如獲得下星期的日期)提供了一些方法 
                                                                                  

Calendar類:這個類使用Calendar . MONTH,輸出的時候需要加1,纔是需要的月份,MONTH是從0開始計算的;
                                                                                  

Date和String之間的相互轉換:
        1> Date date=new Date();
      String s=new SimpleDateFormat("yyyy-MM-dd").format(date);
2> String ss="2323-2-22";
      Date d=new SimpleDateFormat("yyyy-MM-dd").parse(ss);
                                                                                  


數組和集合的區別?
1)長度區別:
數組長度固定
集合長度可變
2)內容的區別
數組可以存儲同一種類型的元素
集合可以存儲多種類型的元素
3)存儲類型的區別
數組:可以存儲基本類型,也可以存儲引用類型 String[] str = {"hello","world","java",100} ; 錯誤的
集合:只能存儲引用類型 
                                                                                  


集合Collection中的removeAll():
        c1.removeAll(c2):刪除集合c2中的所有元素,並將刪除元素後的集合賦給c1,但是集合c2中的元素不發生變化;
        c1.containsAll(c2):集合c2中的所有元素都要在c1中能找到纔算包含全部;
        c1.retainAll(c2):c1集合對c2集合取交集,交集的元素要存到c1集合中,boolean返回值表達的c1集合的元素是否發生變化,如果發生變化,則返回true,否則,返回false;
                                                                                  

併發修改異常:
        java.util.ConcurrentModificationException:當方法檢測到對象的併發修改,但不允許這種修改時,拋出此異常;
原因:按照正常的需求,給集合添加元素,遍歷,遍歷同時,判斷集合中是否有需要的元素,有就添加新元素,遍歷的時候,使用迭代器遍歷,但是添加元素,使用集合添加元素.集合添加了一個新的元素,迭代器不知道;
        解決方案:
方式1:要麼使用List集合的特有迭代器遍歷,使用迭代器添加元素!
方式2:要麼使用集合遍歷,使用集合添加元素!

                                                                                  


List集合有三個子實現類:
ArrayList:
1>底層數據結構式數組結構,查詢塊,增刪慢
2>從內存角度考慮:線程不安全的,不同步的,執行效率高
3>多線程:synchronized :同步的意思 解決線程安全問題
sychronized(鎖對象){ 同步代碼 
共享數據;
}
4>解決線程安全問題,通過同步可以解決,但是效率低了...
LinkedList:
1>底層數據結構式鏈表結構,查詢慢,增刪塊
2>從內存角度考慮:線程不安全,不同步,執行效率高
Vector:
1>這是一個線程安全的類,底層數據結構是數組:查詢快,增刪慢
2>線程安全的,同步,執行效率低!
                                                                                  

泛型的好處:
1)將運行時期異常提前到了編譯時期;
2)優化了設計,解決了黃色警告線問題;
3)避免了強制類型轉換;
                                                                                  

泛型的應用:在接口中,類中,方法上應用,在集合中應用最多;

                                                                                  

Set集合和List集合的區別?
Set集合:不允許元素重複,唯一的(元素可以爲null) ,不能保證迭代的順序恆久不變(底層哈希表和hascode);
無序(存儲和取出不一致);
List:允許元素重複,並且存儲特點:有序性(存儲和取出一致);
                                                                                  

現在是自定義的類,HashSet集合的add()方法本身依賴於hashCode()和equals()方法;
解決:在Student類中重寫這兩個方法;
                                                                                  

如果在開發中,元素唯一性,並且還要保證元素有序(存儲和取出一致),使用LinkedHashSet集合;
                                                                                  

LinkedHashSet集合:
底層是一種鏈接列表和哈希表組成;
可以保證元素的唯一性,是由哈希表決定的(hashCode()和equals());
可以保證元素的迭代順序一致(有序),存儲和取出一致,是由鏈表決定;
                                                                                  

TreeSet集合模擬情況下是通過自然順序對集合中的元素排序;
可以保證元素唯一併且元素排序(Integer類型的元素自然升序);
分爲:自然排序       比較器排序;
                                                                                  

TreeSet集合排序:
自然排序:
在定義的類繼承Comparable接口,重寫其中的compareTo()方法;
選擇排序:
使用匿名內部類方式,在TreeSet<Student>()的括號中new Comparator,並重寫方法compare方法;

                                                                                  
 
HashMap集合本身基於哈希表:

它可以保證鍵的唯一性(Map都是針對鍵有效);
                                                                                  

HashMap集合:
如果成員變量的值一樣,認爲是同一個數據;
HashMap底層是哈希表:依賴於hashCode(),equals();
如果集合的健一樣,值不一樣,那麼後邊的值會將前面的值替換掉;
                                                                                  

LinkedHashMap<K,V>:是Map接口基於哈希表和鏈接列表實現的;
哈希表:保證鍵的唯一性;
鏈接列表:保證元素有序性(存儲和取出一致);
                                                                                  

TreeMap集合也可以進行自然排序,比較器排序;
                                                                                  

面試題:
HashMap集合和Hashtable的區別?;
        共同點:都是map接口的實現類,都是基於哈希表的實現類;
        HashMap集合線程不安全的類,不同步,執行效率高(允許鍵和值是null的);
        Hashtable集合線程安全的類,同步,執行效率低(不允許有null鍵和null值) ;
                                                                                  

Collection和Collections的區別:
Collection:頂層次單列集合的根接口,它是一個集合,是一個接口;
Collections:是針對集合操作的工具類,有一些功能:隨機置換,集合裏面的二分查找,將集合的元素進行反轉;
                                                                                  

異常:
編譯時期異常:只要出現的不是運行時期異常,統稱爲編譯時期  ;
編譯時期異常:開發者必須處理!
運行時期異常:RuntimeException;
編譯通過了,但是開發者代碼不嚴謹(NullPointerExceptino等等...);
                                                                                  

 編譯時期異常和運行時期異常的區別?
編譯時期:開發者必須進行顯示處理,不處理,編譯不能通過;
運行時期異常:無需進行顯示處理,可以像編譯時期一樣進行處理;
                                                                                  

throw關鍵字通常用於方法體中,並且跑出一個異常對象;
程序在執行到throw語句是立即停止,它後面的語句都不執行;
如果throw拋出異常後,如果想在上一級代碼中捕獲並處理異常,則需要在拋出異常的方法中使用throws關鍵字在方法的聲明中也要拋出異常;
如果要捕捉throw拋出的異常,則必須使用try-catch語句塊;
                                                                                  

throws和throw的區別?
throws:也是表示拋出異常,它後面跟的異常類名,並且可以多個異常類名中間逗號開;
舉例:
public void show() throws IoException,ClassNotFoundException{...}
在方法上拋出,由調用者處理;
它表示拋出異常的可能性;
  throw:拋出的一個異常對象;
在語句體中拋出的,由語句體進行處理;
  它表示拋出異常的肯定性;
                                                                                  

如果catch裏面有return 語句,finally中的代碼還會執行,是在return語句之前執行還是return後執行?
        解決:finally中代碼是一定會執行的,是在return前
                                                                                  

異常中的注意事項:
子類繼承父類的時候的注意事項 
1> 子類重寫父類的方法的時候,子類的方法的拋出的異常必須要麼是父類的方法異常一樣,要麼是父類方法異常的子類
2> 子類重寫父類方法的時候,如果父類中的這個方法沒有拋出異常,那麼子類重寫的這個方法也不能拋出異常,只能try...catch
                                                                                  

File類:表示文件或者目錄的路徑的抽象表現形式;
                                                                                  

Runnable接口的目的是爲希望在活動時執行代碼的對象提供一個公共協議;
所以在這個類中的成員變量已經被共享,因此不需要給變量添加static;
                                                                                  

同步代碼塊:synchronized(鎖對象){
針對多條語句對共享數據操作代碼;
    }
                                                                                  

校驗一個多線程程序是否有安全問題的隱患的前提條件:
1)當前程序是否是多線程環境 (不能解決)
2)是否有共享數據         (不能解決)
3)是否有多條語句對共享數據進行操作 (同步代碼塊)
                                                                                  


注意:
鎖對象:一定要同一個鎖(每個線程只能使用同一把鎖)
鎖對象:任何的Java類(引用類型)
                                                                                  

線程安全的類:
StringBuffer sb = new StringBuffer() ;
Vector<String> v = new Vector<String>() ;
Hashtable<String, String> hm = new Hashtable<String,String>() ;
                                                                                  

靜態同步方法的鎖對象:類名.class
非靜態的方法鎖對象:this
                                                                                  

兩個或兩個以上的線程,在執行的過程中出現互相等待的情況,就叫做死鎖
                                                                                  

wait(),notify(),notifyAll() 這些方法爲什麼會定義在Object類中呢?
定義在Object類中的原因:這些方法好像是屬於線程的方法,但是Thread類中並沒有這些方法,
因爲多線程中同步鎖對象是任意的Java類,而這些方法都和鎖對象有關係,所以定義在Object類;
                                                                                  

wait()和sleep(long times) 的區別?
1>這兩個方法來自不同的類分別是 Object 和 Thread;
2>最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法(鎖代碼塊和方法鎖)
3>wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep可以在任何地方使用(使用範圍)
4>sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常
                                                                                  

線程池:多個線程執行完畢,它會重新回到線程池中,等待被利用,不會變成垃圾!
特點:1)節約成本;
2)線程執行完畢之後不會變成垃圾,重新回到線程池中,等待被利用;
                                                                                  

多線程實現方式第三種:
前提:自定義類實現Callable接口
1)創建線程池對象: Executors 裏面的那個方法newFixedThreadPool(),返回的是ExecutorsService
  2)然後調用ExecutorsService裏面的提交任務的方法:
  <T> Future<T> submit(Callable<T> task)提交一個返回值的任務用於執行
  Future:表示計算結果;
  3)關閉線程池
                                                                                       
















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章