Java基礎小結

1. Java簡介

1.1 語言起源

  • Java是SUN1995年推出的一門高級編程語言
  • 2004年,J2SE1.5發佈,成爲Java語言發展史上的又一里程碑
  • 2009年,Oracle收購SUN,取得Java的版權
  • 2011年,Oracle公司發佈java7的正式版

1.2 Java語言重要特性之跨平臺

  • 跨平臺:即不依賴於操做系統,也不依賴硬件環境。
  • Java的跨平臺的原理:Java的跨平臺是經過Java虛擬機(JVM)來實現的。

1.3 Java的三大平臺

平臺 簡介
Java SE Java SE(Java Platform,Standard Edition)。Java SE 之前稱爲J2SE。它是容許開發和部署在桌面、服務器、嵌入式環境和實時環境中使用的Java 應用程序。Java SE 包含了支持Java Web 服務開發的類,併爲Java Platform,Enterprise Edition(Java EE)提供基礎。
Java EE Java EE(Java Platform,Enterprise Edition)。這個版本之前稱爲J2EE。企業版本幫助開發和部署可移植、健壯、可伸縮且安全的服務器端 Java 應用程序。Java EE 是在Java SE 的基礎上構建的,它提供Web 服務、組件模型、管理和通訊API,能夠用來實現企業級的面向服務體系結構(service-oriented architecture,SOA)和Web 2.0 應用程序。
Java ME Java ME(Java Platform,Micro Edition)。這個版本之前稱爲J2ME,也叫K-JAVA。Java ME 爲在移動設備和嵌入式設備(好比手機、PDA、電視機頂盒和打印機)上運行的應用程序提供一個健壯且靈活的環境。Java ME 包括靈活的用戶界面、健壯的安全模型、許多內置的網絡協議以及對能夠動態下載的連網和離線應用程序的豐富支持。基於Java ME 規範的應用程序只需編寫一次,就能夠用於許多設備,並且能夠利用每一個設備的本機功能。
Java Card* 支持一些Java小程序(Applets)運行在小內存設備(如智能卡)上的平臺

2. Java基礎部分(基本語法,Java特性等)

2.1 標識符

  • 什麼是標識符

就是程序員在定義Java程序時,自定義的一些名字html

  • 標識符定義規則
  1. 標識符由26個英文字符大小寫(a~zA~Z)、數字(0~9)、下劃線(_)和美圓符號($)組成。
  2. 不能以數字開頭,不能是關鍵字
  3. 嚴格區分大小寫
  4. 標識符的能夠爲任意長度
  • 標識符命名規範
  1. 包名: 多個單詞組成時全部字母小寫(例:package com.zeng)
  2. 類名和接口: 多個單詞組成時全部單詞的首字母大寫(例:HelloWorld)
  3. 變量名和函數名: 多個單詞組成時第一個單詞首字母小寫,其餘單詞首字母大寫(例:lastAccessTime、getTime)。
  4. 常量名: 多個單詞組成時,字母所有大寫,多個單詞之間使用(_)分隔(例:INTEGER_CACHE)

2.2 常量和變量

2.2.1 常量

常量的分類java

  1. 整數常量:全部整數
  2. 小數常量:全部小數
  3. 布爾常量:只有true和false
  4. 字符常量:使用‘’引發來的單個字符
  5. 字符串常量:使用「」引發來的字符序列
  6. null常量:只有一個值null

char類型程序員

  1. char類型表示的是單個字符類型。
  2. 注意:特殊字符的轉義序列:轉義字符
    • 特殊字符使用」\」把其轉化成字符的自己輸出,那麼使用」\」的字符稱做爲轉義字符。
    • 常見轉義字符
      • 轉義字符 名稱 Unicode
      • \b Backspace (退格鍵) \u0008
      • \t Tab (Tab鍵盤) \u0009
      • \n Linefeed (換行) \u000A
      • \r Carriage Return(回車) \u000D
      • \ Backslash (反斜槓) \u005C
      • ' Single Quote (單引號) \u0027
      • " Double Quote (雙引號) \u0022

Boolean類型算法

2.2.2 變量

變量的概述 用於存儲可變數據的容器。編程

  • 變量的數據類型
  1. 整型
    • byte 表明一個字節的大小 8bit -128~127
    • short 表明兩個字節的大小 16bit -2^(15)~2^(15)-1
    • int 表明四個字節的大小 32bit -2^(31)~2^(31)-1
    • long 表明八個字節的大小 64bit -2^(63)~2^(63)-1
    • 若是一個數值沒有采起特殊的處理,那麼該整數默認的類型是int。
    • 可使用數值後面添加L或小寫l改變默認的整數類型。
  2. 浮點型
    • float 表明四個字節的大小 32bit
    • double 表明八個字節的大小 64bit
    • java程序中全部的小數默認的類型是double類型,因此須要使用特殊的符號改變默認的小數類型。
  3. 字符型
    • char 表明兩個字節的大小 16bit
      原理:將字符映射爲碼錶中對應的十進制數據加以存儲。
  4. 布爾型
    • boolean 佔一個字節。只有true與false兩個值。
  • 變量的聲明
  • 格式: 數據類型 變量名字1 , 變量名字2 ,……, 變量名字n;
  • 備註:變量名的首字母都通常都是以小寫字母開始。
  • 變量的初始化
  • 初始化方式1: 數據類型 變量名字 = 數值。
  • 初始化方式2: 數據類型 變量名字 , 變量名字 = 數值

2.3 數據類型

  • 基本數據類型
  • 引用數據類型
  • 數據類型的轉換
    1. 自動類型轉換(也叫隱式類型轉換)
      • 要實現自動類型的轉換,須要知足兩個條件
        • 第1、兩種類型彼此兼容
        • 第2、目標類型取值範圍必須大於源類型
      • 全部的數字類型,包括整形和浮點型彼此均可以進行轉換。
    2. 強制類型轉換(也叫顯式類型轉換)
      • 當兩種類型彼此不兼容,或者目標類型取值範圍小於源類型(目標是byte,源是int)沒法自動轉換,此時就須要進行強制類型轉換。
    3. 表達式的數據類型自動提高
      • 算術表達式,邏輯表達式
      • 全部的byte型、short型和char的值將被提高到int型。
      • 若是一個操做數是long型,計算結果就是long型;
      • 若是一個操做數是float型,計算結果就是float型;
      • 若是一個操做數是double型,計算結果就是double型。
    4. java基本數據類型轉換

2.4 運算符

  • 算數運算符 小程序

  • 賦值運算符數組

    運算符 運算 範例 結果
    = 賦值 a=3,b=2 a=3,b=2
    += 加等於 a=3,b=2;a+=b; a=5,b=2;
    -= 減等於 a=3,b=2,a-=b; a=1,b=2;
    *= 乘等於 a=3,b=2,a*=b; a=6,b=2
    /= 除等於 a=3,b=2,a/=b; a=1,b=2;
    %= 模等於 a=3,b=2,a%=b; a=1,b=2
  • 比較運算符安全

    運算符 運算 範例 結果
    == 相等於 4 == 3 false
    != 不等於 4 != 3 true
    < 小於 4 < 3 false
    > 大於 4 > 3 true
    <= 小於等於 4 <= 3 false
    >= 大於等於 4 >= 3 true
    instanceof 檢查是不是類的對象 "hello" instanceof String true
    • 注意的細節

      使用比較運算符的時候,要求兩種數據類型必須一致
      byte、short、char 會自動提高至int服務器

  • 邏輯運算符網絡

  • 注意

    1. 「&」和「&&」的區別
      單與時,左邊不管真假,右邊都進行運算;雙與時,若是左邊爲真,右邊參與運算,若是左邊爲假,那麼右邊不參與運算。
    2. 「|」和「||」的區別
      同理,雙或時,左邊爲真右邊不參與運算。
    3. 「 ^ 」異或與「|」或的不一樣之處
      當左右都爲true時,結果爲false
  • 位運算符

    位運算符 運算符含義
    & 與(AND)
    | 或(OR)
    ^ 異或
    ~ 取反
    當參與取反的數值是正數時,把對應的值加上負號,再-1;
    當參與取反的數值是負數時,把對應的值加上負號,再-1;
    負數的表現形式就是對應的正數取反,再加1。負數的最高位確定是1.
  • 移位運算符

    運算符 運算 範例 注意
    << 左移 3 << 2 --> 3*2*2=12 空位補0,被移除的高位丟棄,空缺位補0
    >> 右移 3 >> 1 --> 3/2=1 被移位的二進制最高位是0,右移後,空缺位補0; 最高位是1,空缺位補1
    >>> 無符號右移 3 >>> 1 --> 3/2=1 被移位二進制最高位不管是0或者是1,空缺位都用0補
  • 三元運算符

    格式 (條件表達式) ? 表達式1 :表達式2;

  • 運算符的優先級與結合性

2.5 流程控制語句

  • if else
  • switch
    • switch語句選擇的類型只有四種:byte,short,int, char。
      • jdk 1.7容許switch中有String變量和文本
    • case之間與default沒有順序。先判斷全部的case,沒有匹配的case執行default。
    • switch語句中止的條件是遇到了break關鍵字或者結束switch語句的大括號。
    • 若是匹配的case或者default沒有對應的break,那麼程序會繼續向下執行,運行能夠執行的語句,直到遇到break或者switch結尾結束。
    • switch case中的值必需要與switch表達式的值具備相同的數據類型。並且case後跟的值必須是常量,不能跟變量。
  • while,do while
  • for循環
    • for和while區別
      1. for裏面的兩個表達式運行的順序,初始化表達式只讀一次,判斷循環條件,爲真就執行循環體,而後再執行循環後的操做表達式,接着繼續判斷循環條件,重複整個過程,直到條件不知足爲止。
      2. while與for能夠互換,區別在於for爲了循環而定義的變量在for循環結束時就在內存中釋放。而while循環使用的變量在循環結束後還能夠繼續使用。
      3. 最簡單無限循環格式:while(true) , for(;;),無限循環存在的緣由是並不知道循環多少次,而是根據某些條件來控制循環。推薦使用while(true)
  • break、continue關鍵字

方法(函數)

  • 格式
修飾符 返回值類型 函數名(參數類型 形式參數1,參數類型 形式參數2,…)
	{
		執行語句;
		return 返回值;
	}
複製代碼

返回值類型: 運行這段程序得出的一個運算結果類型,若是函數沒有返回值,則用void來表示該函數沒有返回值。
函數名:僅僅是一個標識符,能夠隨意起名字。
形式參數:是一個變量,用於存儲調用函數傳遞進來的實際參數。
實際參數:傳遞給形式參數的具體數值。
返回值: 返回給調用者。

  • 特色
    • 定義函數能夠將功能代碼進行封裝
    • 便於對該功能進行復用
    • 函數只有被調用纔會被執行
    • 函數的出現提升了代碼的複用性
    • 對於函數沒有具體返回值的狀況,返回值類型用關鍵字void表示,那麼該函數中的return語句若是在最後一行能夠省略不寫。
    • 注意:函數中只能調用函數,不能夠在函數內部定義函數。
  • 重載
    • 定義

      在同一個類中,有一個以上的同名函數,只要函數的參數列表或參數類型不同便可,與返回值無關, 這些統稱爲方法的重載。

    • 緣由

      爲了加強方法的閱讀性,優化了程序設計。

2.6 數組

2.7 註釋

  • 註釋的做用

經過註釋提升程序的可讀性,使java程序的條理更加清晰,易於區分代碼行與註釋行。另外一般在程序開頭加入做者,時間,版本,要實現的功能等內容註釋,方便後來的維護以及程序員的交流。

  • 註釋的種類
    • 單行註釋(line comment)用//表示,編譯器看到//會忽略該行//後的全部文本
    • 多行註釋(block comment)用/**/表示,編譯器看到/*時會搜索接下來的*/, 忽略掉/**/之間的文本。
    • 文檔註釋用/** */表示,是java特有的註釋,其中註釋內容能夠被JDK提供的工具 javadoc 所解析,生成一套以網頁文件形式體現的該程序的說明文檔。
    • 文檔註釋
      1. 須要使用sun給咱們提供的javadoc工具生成一個html的說明文檔。
      2. 只能抽取public的屬性或者方法內容。
      3. 格式: javadoc –d 指定存儲文檔的路徑 -version –author(可選) 目標文件

3. 關鍵字

3.1 常見的關鍵字

3.2 關鍵字分類

3.3 全部關鍵字

  • 備註:goto是Java的保留關鍵字,意思是Java並無使用goto,之後是否使用未定

4. 面向對象

4.1 面向對象思想

4.1.1 面向對象的描述

  • 【面向對象】(Object Oriented,簡稱OO),是一種以事物爲中心的編程思想;
  • 【面向對象程序設計】(Object Oriented Programming,簡稱OOP),是一種程序開發的方法。它將對象做爲程序的基本單元,將程序和數據封裝其中,以提升軟件的重用性、靈活性和擴展性。
  • 【面向過程】(Procedure Oriented,簡稱PO)是一種以過程爲中心的編程思想,強調的是功能行爲。

4.1.2 面向對象的特徵

  • 【封裝】(encapsulation):

    把客觀事物封裝成抽象的類,而且類能夠把本身的數據和方法只讓可信的類或對象操做,對不可信的進行信息隱藏。

  • 【繼承】(inheritance):

    繼承是指一種能力:它可使用現有的類的全部功能,並在無需從新編寫原來的類的狀況下對這些功能進行擴展。

  • 【多態】(polymorphism)

    定義時的類型和運行時的類型不同,此時就成爲多態。
    是容許你將父對象設置成一個或更多的他的子對象相等的技術,賦值以後,父對象就能夠根據當前賦值給它的子對象的特性以不一樣的方式運做。
    簡單的說,就是一句話:容許將子類類型的指針賦值給父類類型的指針。

4.1.3 面向對象的五大基本原則

  1. 單一職責原則(SRP)

    一個類的功能要單一,不能一應俱全

  2. 開放封閉原則(OCP)

    一個模塊在擴展性方面是開放的,對更改性方面是封閉的

  3. 里氏替換原則(LSP)

    子類應當替換父類,並出現個在父類可以出現的全部位置

  4. 依賴倒置原則(DIP)

    具體依賴抽象,上層依賴下層

  5. 接口隔離原則(ISP)

    模塊間要經過抽象接口隔開,而不是經過具體的類強行耦合起來

4.2 類與對象

4.2.1 【類】

實際就是對某種類型事物的共同特性與行爲的抽取

4.2.2 【對象】

在現實生活中存在的一個具體的事物

4.3 封裝

封裝的好處

  1. 隱藏了類的具體實現
  2. 操做簡單
  3. 提升對象數據的安全性

4.4 繼承

4.4.1 特色

  1. 描述類和類之間的關係
  2. 下降類和類之間的重複代碼

4.4.2 extends關鍵字

4.4.3 繼承細節

  • 類名的設定

    被繼承的類稱之爲父類(基類),繼承的類稱之爲子類

  • 子類並不能繼承父類中全部的成員
    • 父類定義完整的成員:靜態成員、非靜態、構造函數。靜態變量和靜態方法均可以經過子類名.父類靜態成員的形式調用
    • 全部的私有成員不能繼承
    • 構造函數不能繼承

4.4.4 super關鍵字

  • 做用
    1. 主要存在於子類方法中,用於指向子類對象中的父類對象
    2. 訪問父類的屬性
    3. 訪問父類的函數
    4. 訪問父類的構造函數
  • 注意
    1. this和super很像,this指向的是當前對象的調用,super指向的是當前調用對象的父類。this和super只能在有對象的前提下使用,不能在靜態上下文使用
    2. 子類的構造函數第一行會默認調用父類無參的構造函數,隱式語句
    3. 若是顯式調用父類函數,編譯器自動添加的調用父類無參構造函數就會消失。構造函數間的調用只能放在第一行,只能調用一次。super和this不能同時存在構造函數第一行

4.4.5 重寫(override)

  • 定義

    在繼承中,能夠定義和父類名稱相同且參數列表一致的函數,稱之爲函數的重寫

  • 前提

    必需要有繼承關係

  • 特色
    1. 當子類重寫父類的函數,那麼子類的對象若是調該函數,調用的必定是重寫後的函數;
    2. 可經過super關鍵字進行父類方法的調用;
    3. 子類可經過繼承將父類的方法加強
  • 細節
    1. 函數名、參數列表必須相同
    2. 子類重寫父類的函數時,函數的訪問權限必須大於或等於父類的訪問權限,不然編譯報錯
    3. 子類返回值類型必須是父類函數返回值類型或該返回值類型的子類,不能返回比父類更大的數據類型

4.4.6 子類對象查找屬性或方法時的順序

原則:就近原則 若是子類的對象調用方法,默認先使用this進行查找,若是當前對象沒有找到屬性或方法,找當前對象中維護的super關鍵字指向的對象,若是尚未找到則編譯報錯,找到直接調用

4.4.7 重載和重寫的區別

  • 重載

    前提 全部重載函數必須在同一個類中
    特色 函數名相同,參數列表不一樣,與其餘無關(訪問控制符、返回值類型)
    不一樣 個數不一樣、順序不一樣、類型不一樣

  • 重寫

    前提 繼承
    特色 函數名、參數列表必須相同;子類的返回值類型要等於或小於父類的返回值類型

4.4.8 instanceof關鍵字

  • 做用

    比較運算符:用來判斷一個對象是否屬於指定類的對象

  • 用法 對象 instanceof 類
  • 注意

    使用instanceof關鍵字作判斷時,兩個類之間必須有關係

4.4.9 final關鍵字

  • 修飾成員屬性

    說明成員屬性是常量,不能被修改,且必須賦初值

  • 修飾類
    1. 該類是最終類,不能被繼承
    2. 防止代碼功能被重寫
    3. 該類沒有必要擴展
  • 修飾方法
    1. 該方法是最終方法,不能被重寫
    2. 當一個類被繼承,那麼全部的非私有函數都將被繼承,若是函數不想被子類繼承並重寫,能夠用該final修飾
    3. 當一個類中的函數都被修飾爲final時,能夠將類定義爲final的
    4. 編譯時嘗試將該函數內聯,提升運行效率
  • 修飾形參
    1. 當形參被修飾爲final,那麼該形參在所屬的方法中不能被修改
    2. 項目中主要用於一些只用來遍歷未知數據的函數。將位置變量聲明爲final的。加強數據的安全性

4.4.10 Java取消多繼承

  • 多繼承雖然能使子類同時擁有多個父類的特徵,但其缺點也是顯著的,主要有兩方面
    1. 若是在一個子類繼承的多個父類中擁有相同名字的實例變量,子類在引用該變量時將產生歧義,沒法判斷應該使用哪一個父類的變量;
    2. 若是在一個子類繼承的多個父類中擁有相同方法,子類中又沒有覆蓋該方法,那麼調該方法時將產生歧義,沒法判斷應該調用哪一個父類的方法
  • 注意
    1. 子類將繼承父類全部的數據域和方法。靜態方法能夠繼承,可是不能重寫;私有方法能夠繼承,只是不能調用
    2. java類是單繼承,接口能夠實現多繼承

4.5 多態

  • 多態的概念

    所謂多態就是指一個類實例的相同方法在不一樣情形下有不一樣的表現形式,多態機制使具備不一樣內部結構的對象能夠共享相同的外部接口

  • 多態體現
    1. 父類和子類有相同的成員變量,多態下訪問的是父類的成員變量;
    2. 當父類和子類具備相同的非靜態方法(就是子類重寫父類的非靜態方法),多態下訪問的是子類的成員方法;
    3. 當父類和子類具備相同的靜態方法(就是子類重寫父類的靜態方法),多態下訪問的是父類的靜態方法

4.6 成員變量和局部變量

  • 成員變量屬於對象,它存儲在堆內,堆內的實體,當沒有引用指向其時,才垃圾回收清理;
  • 局部變量存在棧內存中,當再也不使用時,立刻就會被釋放。

4.7 匿名對象

  • 概念

    沒有名字的實體,也就是該實體沒有對應的變量名引用

  • 用途
    1. 當對象對方法進行一次調用的時候,可使用匿名對象對代碼進行簡化
    2. 匿名對象能夠做爲實參進行傳遞
  • 注意

    匿名對象的屬性沒法獲取,由於沒有引用變量指向該對象

4.8 構造方法

  • 構造方法與普通函數的區別
    1. 通常函數是用於定義對象應該具有的功能。而構造函數定義的是,對象在調用功能以前,在創建時,應該具有的一些內容,也就是對象的初始化內容。
    2. 構造函數是在對象創建時由JVM調用,對對象初始化。通常函數是對象創建後,當對象調用該功能時纔會執行。
    3. 普通函數可使用對象屢次調用,構造函數只在對象建立時調用。
    4. 構造函數的函數名要與類名同樣,而普通的函數只要符合標識符的命名規則便可。
    5. 構造函數沒有返回值類型。
  • 構造函數注意的細節
    1. 當類中沒有定義構造函數時,系統會指定給該類加上一個空參數的構造函數。這個是類中默認的構造參數。當類中若是定義類構造函數,這時默認的構造函數就沒有了
    2. 在一個類中能夠定義多個構造函數,以進行不一樣的初始化。多個構造函數存在於類中,是以重載的形式體現的,由於構造函數的名稱都相同
  • 構造代碼塊
    • 做用

      給全部的對象進行統一的初始化

    • 與構造函數的區別

      構造代碼塊是給全部對象進行統一初始化,構造函數給對應的對象進行初始化

  • 靜態代碼塊

    隨着類的加載而加載。只執行一次,優先於主函數。用戶給類進行初始化

4.9 this關鍵字

  • 概念

    this關鍵字表明的是對象的引用。即this指向一個對象,所指向的對象就是調用該函數的對象引用。

  • 注意
    1. this只能在非靜態(沒有static修飾的)函數中使用;
    2. 構造函數相互調用必須放在構造函數的第一個語句,不然編譯報錯;
    3. 能夠解決構造函數中對象屬性和函數形參的同名問題。

4.10 static關鍵字

  • 做用

    實現對象之間重複屬性的數據共享

  • 使用

    主要用於修飾類的成員

    • 成員變量
      1. 非靜態成員變量:須要建立對象來訪問
      2. 靜態成員變量:使用類名直接調用,也能夠經過對象訪問
    • 成員方法
      1. 靜態函數
        靜態函數中不能訪問非靜態成員變量,只能訪問靜態變量
        靜態方法不能夠出現this,super關鍵字
        由於靜態優先於對象存在
      2. 非靜態函數
        非靜態函數中能夠訪問靜態成員變量
    • 靜態代碼塊
  • 特色
    1. 靜態會隨着類的加載而加載,隨着類的消失而消失。聲明週期很長
    2. 優先於對象而存在
    3. 被全部實例(對象)所共享
    4. 能夠直接被類名調用
  • 優缺點
    • 優勢:對對象的共享數據進行單獨空間的存儲,節省空間
    • 缺點:生命週期過長,訪問出現侷限性(靜態只能訪問靜態)
  • 靜態變量(類變量)和實例變量的區別
    • 存放位置
      1. 類變量隨着類的加載而加載存在於方法區中
      2. 實例變量隨着對象的創建而存在於堆內存中
    • 聲明週期
      1. 類變量生命週期最長,隨着類的消失而消失
      2. 實例變量生命週期隨着對象的消失而消失
  • 應用

    自定義數據工具箱

4.11 內部類

基礎

  • 成員內部類
    • 訪問方式
      1. 內部類能夠直接訪問外部類的成員屬性和成員方法(包括private成員和靜態成員)
      2. 外部類須要訪問內部類的成員屬性時,須要建立內部類的對象
        • 在外部類的成員函數中建立內部類的對象,經過內部類對象直接訪問內部類的成員
        • 在其餘類中直接建立內部類的對象:
          • 第一種方式:Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();// 必須經過Outer對象來建立
          • 第二種方式:Outer.Inner inner1 = outer.getInnerInstance();
      3. 若是要訪問外部類的同名成員,須要如下面的形式進行訪問
        • 外部類.this.成員變量
        • 外部類.this.成員方法
      4. 內部類能夠擁有private訪問權限、protected訪問權限、public訪問權限和包訪問權限
    • 優點

      成員內部類做爲外部類的成員,那麼能夠訪問外部類的任意成員

    • 特色
      1. 私有的成員內部類:不能在其餘類中直接建立內部類對象來訪問
      2. 靜態的成員內部類:若是內部類中包含靜態成員,那麼Java規定內部類必須聲明爲靜態的
      3. 訪問靜態內部類的格式:Outer.Inner in = new Outer.Inner()
  • 局部內部類
    • 訪問方式

      能夠直接在包含局部內部類的方法中建立局部內部類的對象,調用局部內部類的成員

    • 特色
      1. 不能使用任何的訪問修飾符
      2. 會生成兩個.class文件,一個是Outer.class,另外一個是Outer$LocalInner.class
      3. 局部內部類只能訪問方法中聲明的final類型的變量(能夠訪問獲取值,可是不能修改,系統會默認添加final屬性)
    • 緣由
      1. 由於局部內部類最終會被編譯爲一個單獨的類,其所訪問的局部變量會成爲這個類的屬性
      2. 若是訪問的一個值類型局部變量,就會形成這個類的屬性與所訪問的局部變量不是同一個,會形成數據不一樣步
      3. 因此強制要求局部變量必須爲final,避免數據不一樣步
  • 匿名內部類

    就是沒有類名字的內部類
    通常使用匿名內部類的方法來編寫事件監聽代碼
    匿名內部類也是不能有訪問修飾符和static修飾符的
    匿名內部類是惟一一種沒有構造器的類

    • 做用

      簡化內部類書寫

    • 前提:

      必須繼承一個類或者是實現一個接口

    • 注意細節

      使用匿名內部類時,若是須要調用匿名內部類的兩個方法或者兩個方法以上,可使用變量指向該對象

  • 靜態內部類

    靜態內部類是不須要依賴於外部類的,這點和類的靜態成員屬性有點相似,而且它不能使用外部類的非static成員變量或方法

深刻理解內部類

  • 爲何局部內部類和匿名內部類只能訪問局部final變量?

    背景:當test方法執行完畢以後,變量a的生命週期就結束了,而此時Thread對象的生命週期極可能尚未結束,那在再Thread的run方法中繼續訪問變量a就變成了不可能了,可是又要實現這樣的效果,怎麼辦呢?Java採用了【複製】的手段來解決這個問題

    方案:也就是說若是局部變量的值在編譯期間就能夠肯定,則直接在匿名內部裏面建立一個拷貝。若是局部變量的值沒法在編譯期間肯定,則經過構造器傳參的方式來對拷貝進行初始化賦值。
    解決:java編譯器就限定必須將入參變量限制爲final變量

4.12 抽象類

當描述一個類的時候,若是不能肯定功能函數如何定義,那麼該類就能夠定義爲抽象類,功能函數應該描述爲抽象函數

  • 特色
    1. 有抽象函數的類,該類必定是抽象類
    2. 抽象類中不必定要有抽象函數
    3. 抽象類不能使用new建立對象
    4. 編譯器強制子類實現抽象類父類的未實現的方法
    5. 能夠不實現,前提是子類的也要聲明爲抽象的
  • 優勢
    1. 提升代碼的複用性
    2. 提升代碼的擴展性,便於後期的代碼維護
  • 構造函數

    抽象類中必定有構造函數,主要爲了初始化抽象類中的屬性,一般由子類實現

  • 注意細節
    1. 抽象類能夠沒有抽象方法
    2. 抽象類能夠繼承普通類與抽象類
    3. 抽象類不能直接使用類名建立實例,可是有構造方法,構造方法是讓子類進行初始化
    4. 抽象類必定有構造方法
    5. abstract與其餘修飾符的關係
      • final與abstract不能共存:
        final:它的做用是修飾類表明不能夠繼承,修飾方法不可重寫;
        abstract:修飾類就是用來被繼承的,修飾方法就是用來重寫的;
      • static與abstract不能共存:
        abstract修飾的方法沒有具體的方法實現,因此不能直接調用
        static修飾的方法能夠用類名調用
      • private與abstract不能共存:
        private修飾的只能在本類中使用
        abstract方法是用來被子類進行重寫的,有矛盾

4.13 接口

Java中的接口主要是用來拓展定義類的功能,能夠彌補Java中單繼承的缺點

  • 接口的定義格式
interface 接口名{
	屬性;
	抽象方法;
}
複製代碼
  • 注意

    接口中的全部屬性,默認的修飾符是public static final
    接口中的全部方法,默認的修飾符是public abstract

  • 接口的特色
    1. 類實現接口能夠經過implements實現,實現接口的時候必須把接口中的全部方法實現,一個類能夠實現多個接口;
    2. 接口中定義的全部屬性默認是public static final的,即靜態常量,因此定義的時候必須賦值;
    3. 接口中定義的方法不能有方法體,接口中定義的方法默認添加public abstract;
    4. 有抽象函數的不必定是抽象類,也能夠是接口;
    5. 因爲接口中的方法默認都是抽象的,因此不能被實例化;
    6. 對於接口而言,可使用子類來實現接口中未被實現的功能函數;
    7. 若是實現類中要訪問接口中的成員,不能使用super關鍵字。由於二者之間沒有顯式繼承關係,何況接口中成員屬性是靜態的。可使用接口名直接訪問。
    8. 接口沒有構造方法。
  • 接口與類之間的關係

    接口與類之間是實現關係。非抽象類實現接口時,必須把接口裏面的全部方法實現。類與接口之間是能夠多實現的(即一個類能夠實現多個接口)。

4.14 接口和抽象類的區別

4.15 包機制

  • 使用

    package 包名

  • 包的優勢
    1. 防止類文件衝突;
    2. 使源文件與類文件分離,便於軟件最終發佈。
  • 注意細節
    1. 一個Java類只能定義在一個包中;
    2. 包語句確定是描述類的第一條語句。
  • 包機制引起的問題

    有了包以後,每次訪問類都須要把包名和類名寫全。

    • 解決辦法: import 包名.類名
  • 注意細節

    from xx import *;
    使用「*」不能導入包中子類包的class文件; import語句能夠是多條的。

4.16 訪問修飾符

  • 修飾類成員
    1. 成員使用private修飾,只在本類中使用;
    2. 若是一個成員沒有使用任何修飾符,就是default,該成員能夠被包中的其餘類訪問;
    3. 成員被protected修飾,能夠被包中其餘類訪問,而且位於同一個包中的子類也能夠訪問;
    4. public修飾的成員能夠被全部類訪問。
  • 修飾類
    1. 類只有兩種:public和默認(成員內部類可使用private);
    2. 父類不能夠是private和protected,子類沒法繼承;
    3. public類能夠被全部類訪問;
    4. 默認類只能被同一個包中的類訪問。

4.17 jar包

jar包就是打包文件
jar包是一種打包文件java active file,與zip兼容,稱之爲jar包

  • jar命令
    1. jar工具存放在jdk的bin目錄中(jar.exe);
    2. jar工具:主要用於對class文件進行打包(壓縮);
    3. dos中輸入jar查看幫助
  • 詳細命令
    jar cvf test.jar cn
      1:jar cf test.jar cn 在當前目錄生成test.jar 文件,沒有顯示執行過程
      2:jar cvf test.jar cn 顯示打包中的詳細信息
      3:jar tf test.jar  顯示jar文件中包含的全部目錄和文件名
      4:jar tvf test.jar 顯示jar文件中包含的全部目錄和文件名大小,建立時間詳細信息
      5:jar xf test.jar  解壓test.jar到當前目錄,不顯示信息
      6:jar xvf test.jar 解壓test.jar到當前目錄,顯示詳細信息
      7:可使用WinRaR進行jar解壓
      8;將兩個類文件歸檔到一個名爲 test2.jar 的歸檔文件中:
      	jar cvf test2.jar Demo3.class Demo4.class
      9:重定向
      	1:tvf能夠查看jar文件內容,jar文件大,包含內容多,dos看不全。
      	2:查看jdk中的rt.jar 文件 jar tvf rt.jar
      	3:jar tvf rt.jar>d:\rt.txt
    複製代碼

5 集合部分

5.1 什麼是集合?

存儲對象的容器,集合中能夠存儲任意類型的對象,並且長度可變

5.2 集合和數組的區別

  • 數組和集合類都是容器
  • 數組長度是固定的,集合長度是可變的。
  • 數組中能夠存儲基本數據類型,集合只能存儲對象;
  • 數組中存儲數據類型是單一的,集合中能夠存儲任意類型的對象。

5.3 集合類的特色

用於存儲對象,長度是可變的,能夠存儲不一樣類型的對象

5.4 集合的分類

5.4.1 集合類的繼承實現關係

5.4.2 Collection

Collection描述的是集合公有的功能(CURD)

  • Collection接口的共性方法
    • 增長

      add 將指定對象存儲到容器中; add 方法的參數類型是Object 便於接收任意對象
      addAll 將指定集合中的元素添加到調用該方法和集合中

    • 刪除

      remove() 將指定的對象從集合中刪除
      removeAll() 將指定集合中的元素刪除

    • 修改

      clear() 清空集合中的全部元素

    • 判斷

      isEmpty() 判斷集合是否爲空
      contains() 判斷集合何中是否包含指定對象
      containsAll() 判斷集合中是否包含指定集合
      equals()判斷兩個對象是否相等

    • 獲取

      int size() 返回集合容器的大小

    • 轉成數組

      toArray() 集合轉換數組

  • List:有存儲順序,可重複
  • List特有的方法
    • 增長

      void add(int index, E element) 指定位置添加元素
      boolean addAll(int index, Collection c) 指定位置添加集合

    • 刪除

      E remove(int index) 刪除指定位置元素

    • 修改

      E set(int index, E element) 返回的是須要替換的集合中的元素

    • 查找

      E get(int index) 注意: IndexOutOfBoundsException
      int indexOf(Object o) // 找不到返回-1
      lastIndexOf(Object o)

    • 取子集合

      List subList(int fromIndex, int toIndex) // 不包含toIndex

  • ArrayList(數組實現,查找快,增刪慢)
    • 原理
      1. 數組的內存空間地址是連續的。
      2. ArrayList底層維護了一個Object[] 用於存儲對象,默認數組的長度是10。能夠經過 new ArrayList(20)顯式的指定用於存儲對象的數組的長度。當默認的或者指定的容量不夠存儲對象的時候,容量自動增加爲原來的容量的1.5倍。
      3. 因爲ArrayList是數組實現, 在增和刪的時候會牽扯到數組增容, 以及拷貝元素. 因此慢。數組是能夠直接按索引查找, 因此查找時較快。
  • LinkedList(鏈表實現,增刪快,查找慢)
    • 原理
      1. 因爲LinkedList在內存中的地址不連續,須要讓上一個元素記住下一個元素.因此每一個元素中保存的有下一個元素的位置.雖然也有角標,可是查找的時候,須要從頭往下找,顯然是沒有數組查找快的。可是,鏈表在插入新元素的時候,只須要讓前一個元素記住新元素,讓新元素記住下一個元素就能夠了.因此插入很快。
      2. 因爲鏈表實現, 增長時只要讓前一個元素記住本身就能夠, 刪除時讓前一個元素記住後一個元素, 後一個元素記住前一個元素. 這樣的增刪效率較高。
      3. 但查詢時須要一個一個的遍歷, 因此效率較低。
    • 特有的方法
      1. addFirst(E e)
      2. addLast(E e)
      3. getFirst()
      4. getLast()
      5. removeFirst()
      6. removeLast()
      7. element() 獲取但不移除列表的頭;若是集合中沒有元素,獲取或者刪除元素拋出:NoSuchElementException
        • push()
        • pop()
      8. 隊列(雙端隊列)
        • offer()
        • poll()
        • descendingIterator() 返回逆序的迭代器對象
  • ArrayList和LinkedList的存儲查找的優缺點
    • ArrayList 是採用動態數組來存儲元素的,它容許直接用下標號來直接查找對應的元素。可是,可是插入元素要涉及數組元素移動及內存的操做。

      總結:查找速度快,插入操做慢。

    • LinkedList 是採用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快
  • Set:無存儲順序,不可重複
    • 對象的相等性:hashCode和equals
      1. equals爲true==>hashCode相等,兩個對象相等
      2. hashCode不相等==>equals爲false,兩個對象不相等
      3. hashCode相等==>equals不必定爲true,兩個不一樣的對象可能會有相同的hash值(哈希碰撞)
    • ==和equals的區別
      1. ==是運算符,用於比較兩個變量是否相等,基本類型用==,比較的是它們的值,對象用==,比較的是內存地址,對象類型不一樣返回false
      2. equals是進行邏輯比較,因此一般須要重寫該方法來提供邏輯一致性的比較
  • HashSet

    線程不安全,存取速度快,底層是以哈希表實現的

    • HashSet不存入重複元素:

      元素的哈希值是經過元素的hashcode方法 來獲取的, HashSet首先判斷兩個元素的哈希值,若是哈希值同樣,接着會比較equals方法 若是 equls結果爲true ,HashSet就視爲同一個元素。若是equals 爲false就不是同一個元素。

      哈希值相同equals爲false的元素是怎麼存儲呢,就是在一樣的哈希值下順延(能夠認爲哈希值相同的元素放在一個哈希桶中)。也就是哈希同樣的存一列。

    • HashSet的add()方法的返回值是Boolean類型,元素重複則添加失敗,返回false;元素不重複則添加成功,返回true。

  • TreeSet

    紅-黑樹的數據結構,默認對元素進行天然排序(String),若是在比較的時候兩個對象返回值爲0,那麼元素重複。

    • 紅黑樹

      紅黑樹是一種特定類型的二叉樹

      紅黑樹的算法規則:左小右大

    • TreeSet的排序規則

      1)讓存入的元素自定義比較規則
      2)給TreeSet指定排序規則

      • 方式一:元素自身具有比較性 元素自身具有比較性,須要元素實現Comparable接口,重寫compareTo方法,也就是讓元素自身具有比較性,這種方式叫作元素的天然排序也叫作默認排序。
      • 方式二:容器具有比較性 當元素自身不具有比較性,或者自身具有的比較性不是所須要的。那麼此時可讓容器自身具有。須要定義一個類實現接口Comparator,重寫compare方法,並將該接口的子類實例對象做爲參數傳遞給TreeMap集合的構造方法。
      • 注意 當Comparable比較方式和Comparator比較方式同時存在時,以Comparator的比較方式爲主;
        在重寫compareTo或者compare方法時,必需要明確比較的主要條件相等時要比較次要條件。(假設姓名和年齡一直的人爲相同的人,若是想要對人按照年齡的大小來排序,若是年齡相同的人,須要如何處理?不能直接return 0,由於可能姓名不一樣(年齡相同姓名不一樣的人是不一樣的人)。此時就須要進行次要條件判斷(須要判斷姓名),只有姓名和年齡同時相等的才能夠返回0.)
  • LinkedHashSet

    會保存插入的順序

  • Vector:線程安全
    • 比較

      ArrayList: 單線程效率高;
      Vector: 多線程安全的,因此效率低。

    • 特有的方法

      void addElement(E obj) 在集合末尾添加元素
      E elementAt( int index) 返回指定角標的元素
      Enumeration elements() 返回集合中的全部元素,封裝到Enumeration對象中

  • Enumeration 接口

    boolean hasMoreElements() 測試此枚舉是否包含更多的元素。
    E nextElement() 若是此枚舉對象至少還有一個可提供的元素,則返回此枚舉的下一個元素。

5.4.3 迭代器

對 Collection 進行迭代的類,稱其爲迭代器

  • Iterable

    Collection的父接口. 實現了Iterable的類就是可迭代的.

  • Iterator

    Iterator iterator() 返回該集合的迭代器對象

    • Iterator接口定義的方法
      1. boolean hasNext() 判斷集合中是否有元素,若是有元素能夠迭代,就返回true。
      2. E next() 返回迭代的下一個元素,注意: 若是沒有下一個元素時,調用next元素會拋出NoSuchElementException
      3. void remove() 從迭代器指向的集合中移除迭代器返回的最後一個元素(可選操做)。
      4. 使用迭代器清空集合
      Iterator it = coll.iterator();
       while (it.hasNext()) {
           it.next();
           it.remove();
       }
      複製代碼
    • 細節
      1. 若是迭代器的指針已經指向了集合的末尾,那麼若是再調用next()會返回NoSuchElementException異常
      2. 若是調用remove以前沒有調用next是不合法的,會拋出IllegalStateException
      3. 注意在對集合進行迭代過程當中,不容許出現迭代器之外的對元素的操做,由於這樣會產生安全隱患,java會拋出異常併發修改異常(ConcurrentModificationException),普通迭代器只支持在迭代過程當中的刪除動做。
      • ConcurrentModificationException: 當一個集合在循環中即便用引用變量操做集合又使用迭代器操做集合對象, 會拋出該異常。
    • List特有的迭代器【ListIterator】
      1. public interface ListIterator extends Iterator
      2. ListIterator listIterator()
      3. 方法
        • add(E e) 將指定的元素插入列表(可選操做)。該元素直接插入到 next 返回的下一個元素的前面(若是有)
        • void set(E o) 用指定元素替換 next 或 previous 返回的最後一個元素
        • hasPrevious() 逆向遍歷列表,列表迭代器有多個元素,則返回 true。
        • previous() 返回列表中的前一個元素。
      4. 與Iterator對比
        • Iterator在迭代時,只能對元素進行獲取(next())和刪除(remove())的操做。
        • 對於 Iterator 的子接口ListIterator 在迭代list 集合時,還能夠對元素進行添加(add(obj)),修改set(obj)的操做。

5.4.4 Map

  • Map和Collection的對比
    1. Map一次存一對元素, Collection 一次存一個。Map 的鍵不能重複,保證惟一。
    2. Map 一次存入一對元素,是以鍵值對的形式存在.鍵與值存在映射關係.必定要保證鍵的惟一性.
  • HashMap

    底層是哈希表數據結構,要保證鍵的惟一性,必須覆蓋hashCode方法和equals方法

  • HashTable

    底層是哈希表數據結構

  • HashMap和HashTable的區別
    1. 線程同步
      • HashMap線程不一樣步
      • HashTable線程同步
    2. null做爲鍵和值
      • HashMap能夠存入null鍵、null值;
      • HashTable不能夠
    3. 繼承實現
      • HashMap繼承AbstractMap,實現Map
      • HashTable繼承Dictionary,實現Map
    4. 遍歷方式
      HashTable能夠用Enumeration
    5. 哈希值的使用方式
      • HashMap從新計算hash值,並且用&代替求模
      • HashTable直接使用對象的hash值
    6. 內部實現的初始大小
      • HashMap初始16,並且必定是2的倍數
      • HashTable初始11,擴容:old*2+1
  • HashTable和ConcurrentHashMap的區別
    • HashTable對整張表加鎖
    • ConcurrentHashMap將Hash表分爲16個桶(segment),每次只對須要的桶加鎖 (jdk1.8 時,對Node的節點加鎖,大大提升了併發度)
  • TreeMap

    TreeMap能夠對集合中的鍵進行排序,其實現與TreeSet同樣

  • 經常使用方法
    • 添加

      V put(K key, V value)(能夠相同的key值,可是添加的value值會覆蓋前面的,返回值是前一個,若是沒有就返回null)
      putAll(Map<? extends K,? extends V> m) 從指定映射中將全部映射關係複製到此映射中(可選操做)。

    • 刪除

      remove() 刪除關聯對象,指定key對象
      clear() 清空集合對象

    • 獲取

      value get(key); 能夠用於判斷鍵是否存在的狀況。當指定的鍵不存在的時候,返回的是null
      int size()

    • 判斷
      1. boolean isEmpty() 長度爲0返回true不然false
      2. boolean containsKey(Object key) 判斷集合中是否包含指定的key
      3. boolean containsValue(Object value) 判斷集合中是否包含指定的value
  • 遍歷Map的方式
    • 一、將map 集合中全部的鍵取出存入set集合

      Set keySet() 返回全部的key對象的Set集合(Iterator),再經過get方法獲取鍵對應的值。

    • 二、 values() ,獲取全部的值.

      Collection values()不能獲取到key對象

    • 三、 Map.Entry對象 推薦使用 重點

      Set<Map.Entry<k,v>> entrySet()

      • 將map 集合中的鍵值映射關係打包成一個Map.Entry對象
      • 經過Map.Entry 對象的getKey,getValue獲取其鍵和值。

5.4.5 Collections和Arrays

  • Collections

    Collections:集合框架中的工具類,特色:該工具類中的方法都是靜態的。

    • Collections常見方法
      1. 對list進行二分查找:
        前提該集合必定要有序。
        int binarySearch(list,key);//必須根據元素天然順序對列表進行升級排序
        int binarySearch(list,key,Comparator);//要求list 集合中的元素都是Comparable 的子類。
      2. 對list集合進行排序:
        sort(list); //對list進行排序,其實使用的,是list容器中的對象的compareTo方法
        sort(list,comaprator);//按照指定比較器進行排序
      3. 對集合取最大值或者最小值:
        max(Collection)
        max(Collection,comparator)
        min(Collection)
        min(Collection,comparator)
      4. 對list集合進行反轉:
        reverse(list);
      5. 對比較方式進行強行逆轉
        Comparator reverseOrder();
        Comparator reverseOrder(Comparator);
      6. 對list集合中的元素進行位置的置換
        swap(list,x,y)
      7. 對list集合進行元素的替換。若是被替換的元素不存在,那麼原集合不變
        replaceAll(list,old,new)
      8. 能夠將不一樣步的集合變成同步的集合
        Set synchronizedSet(Set s)
        Map synchronizedMap(Map<K,V> m)
        List synchronizedList(List list)
      9. 將集合變數組
        toArray
  • Arrays

    Arrays:用於對數組操做的工具類

    • Arrays常見方法
      1. 二分查找,數組須要有序
        binarySearch(int[])
        binarySearch(double[])
      2. 數組排序
        sort(int[])
        sort(char[])
        ……
      3. 將數組變成字符串
        toString(int[])
      4. 複製數組
        copyOf();
      5. 複製部分數組
        copyOfRange()
      6. 比較兩個數組是否相同
        equals(int[],int[])
      7. 將數組變成集合
        • List asList(T[])
        • 這樣能夠經過集合的操做來操做數組中元素,可是不可使用增刪方法,add,remove。由於數組長度是固定的,會出現UnsupportOperationExcetion。
        • 可使用的方法:contains,indexOf ……
          • 若是數組中存入的基本數據類型,那麼asList會將數組實體做爲集合中的元素。
          • 若是數組中的存入的引用數據類型,那麼asList會將數組中的元素做爲集合中的元素。
相關文章
相關標籤/搜索