因爲最近一個項目須要,須要學習JAVA知識,學習的過程當中作了一些筆記,主要以知識點記錄爲主,如今分享出來供參考.大部份內容是參考的自強學堂.這裏作了概括.
接口:html
在JAVA中,接口可理解爲對象間相互通訊的協議,接口在繼承中扮演着很重要的角色 接口只定義派生要用到的方法,但方法的具體實現徹底取決於派生類
JAVA面向對象中支持的基本概念:java
封裝,繼承,多態,抽象,類,對象,實例,方法,消息解析
類:git
是一個模板,它描述一類對象的行爲和狀態,建立JAVA對象的模板
對象:程序員
類的一個實例,有狀態和行爲
類變量:正則表達式
聲明在類中,方法體以外,但必須聲明爲static類型
構造方法:shell
在建立一個對象的時候,至少要調用一個構造方法,構造方法的名稱必須與類同名,一個類能夠有多個構造方法
建立對象:express
須要三步:1.聲明,聲明一個對象,包括對象名稱和類型 2.實例化,使用關鍵字new來建立一個對象 3.初始化,使用new建立對象時,會調用構造方法初始化對象 public class Puppy{ public Puppy(String name){ //這個構造器僅有一個參數:name System.out.println("Passed Name is :" + name); } public static void main(String[] args){ Puppy myPuppy = new Puppy("zhangtong"); } }
源文件聲明規則:編程
一個源文件中只能有一個public類 一個源文件能夠有多個非public類 源文件的名稱應該和public的類名保持一致. 若是一個類定義在某個包中,那麼package語句應該放在源文件的首行 若是源文件包含import語句,那麼應該放在package語句和類定義之間。若是沒有package語句,那麼import語句應該在源文件中最前面 import語句和package語句對源文件中定義的全部類都有效。在同一源文件中,不能給不一樣的類不一樣的包聲明
引用類型api
引用類型變量由類的構造函數建立,可使用它們訪問所引用的對象. 對象、數組都是引用數據類型 全部引用類型的默認值都是null 一個引用變量能夠用來引用與任何與之兼容的類型
常量數組
是一個固定值,不須要計算,直接表明相應的值,不能改變 final double PI = 3.1415926; 常量名通常大寫 字面量能夠賦給任何內置類型的變量 byte a = 68; char a = 'A'; 字符串常量和字符常量均可以包括任何Unicode字符 char a = '\u0001'; String a = "\u0001";
轉義字符
Java支持一些特殊的轉義字符序列 \n 換行 \r 回車 \f 換頁符 \b 退格 \s 空格 \t 製表符 \" 雙引號 \' 單引號 \\反斜槓 \ddd 八進制字符 \uxxx 16進制unicode字符
Java支持的變量類型
局部變量, 成員變量, 類變量(靜態變量) 局部變量聲明在方法,構造方法或者語句塊中 局部變量在方法,構造方法,或者語句塊被執行的時候建立,當它們執行完成後,變量將會被銷燬 訪問修飾符不能用於局部變量 局部變量只能在聲明它的方法,構造方法或者語句塊中可見 局部變量在棧上分配 局部變量沒有默認值,因此局部變量被聲明後,必須通過初始化纔可以使用 實例變量聲明在一個類中,但在方法,構造方法和語句塊以外 當一個對象被實例化以後,每一個實例變量的值就跟着肯定 實例變量在對象建立的時候建立,在對象銷燬的時候銷燬 實例變量的值應該至少被一個方法,構造方法或者語句塊引用,使得外部可以經過這些方式獲取實例變量的信息 訪問修飾符能夠修飾實例變量 實例變量對於類中的方法,構造方法或者語句塊是可見的,通常狀況下應該把實例變量設爲私有. 實例變量具備默認值,數值類型的默認值是0,布爾變量的默認值是false,引用類型變量的默認值是null. 類變量以static關鍵字聲明,但必須在構造方法和語句塊以外. 不管一個類建立了多少個對象,類只擁有類變量的一份拷貝 靜態變量除了被聲明爲常量外不多使用,常量是指聲明爲public/private, final 和 static類型的變量,常量初始化後不可改變 靜態變量存儲在靜態存儲區,常常被聲明爲常量 靜態變量在程序開始時建立,在程序結束時銷燬 與實例變量具備類似的可見性,但爲了對類的使用者可見,大多數靜態變量聲明爲public 靜態變量可經過: ClassName.VariableName的方式訪問 類變量被聲明爲public static final類型時,類變量名稱必須使用大寫字母. 若是靜態變量不是public和final類型,其命名方式與實例變量以及局部變量的命名方式一致
訪問控制修飾符
默認的,default,在同一包內可見,不使用任何修飾符 私有的, 以private修飾符指定,在同一類內可見 共有的, 以public修飾符指定,對全部的類可見 受保護的, 以protected修飾符指定,對 同一包內的類和全部子類 可見 接口裏的變量都隱式聲明爲public static final,而接口裏的方法默認狀況下訪問權限是public 類和接口不能被聲明爲private private訪問修飾符的使用主要用來隱藏類的實現細節和保護類的數據 若是幾個相互訪問的public類分佈在不一樣的包中,則須要導入相應public類所在的包, 因爲類的繼承性,類全部的公有方法和變量都能被其子類繼承 接口的成員變量和方法不能聲明爲protected
非訪問修飾符
static修飾符,用來建立方法和類變量 final修飾符,用來修飾類,方法和變量,final修飾的類不能被繼承,修飾的方法不能被繼承類從新定義, 修飾的變量爲常量,是不可修改的. abstract修飾符,用來建立抽象類和抽象方法 synchronized和volatile修飾符,主要用於線程的編程 static修飾符: 靜態變量: static 關鍵字用來聲明獨立於對象的靜態變量,不管一個類實例化多少對象,它的靜態變量只有 一份拷貝.靜態變量也被稱爲類變量. 靜態方法: static 關鍵字用來聲明獨立於對象的靜態方法, 靜態方法不能使用類的非靜態變量. 對類變量和方法的訪問能夠直接使用classname.variablename和classname.methodname的方式訪問. final修飾符: final變量能被顯式地初始化且只能初始化一次,被聲明爲final的對象的引用不能指向不一樣的對象. 可是final對象裏的數據能夠被改變.也就是說final對象的引用不能改變,可是裏面的值能夠改變 final修飾符一般和static修飾符一塊兒使用來建立類常量 類中的final方法能夠被子類繼承,可是不能被子類修改 聲明final方法 的主要目的 是防止該方法的內容被修改. abstract修飾符 抽象類: 不能用來實例化對象,聲明抽象類的 惟一 目的是爲了未來對該類進行擴充 一個類不能同時被abstract和final修飾.若是一個類包含抽象方法,那麼該類必定要聲明爲抽象類 抽象類能夠包含抽象方法和非抽象方法 抽象方法: 抽象方法是一種沒有任何實現的方法,該方法的具體實現由子類提供.抽象方法不能同時被聲明爲final和static 任何繼承抽象類的子類必須實現父類的全部抽象方法,除非該子類也是抽象類 synchronized修飾符 synchronized關鍵字聲明的方法同一時間只能被一個線程訪問. synchronized修飾符能夠應用於四個訪問修飾符. transient修飾符 序列化的對象包好被transient修飾的實例變量時,java虛擬機跳過該特定的變量 該修飾符包含在定義變量的語句中,用來預處理類和變量的數據類型 通常變量被transient修飾,變量將再也不是對象持久化的一部分,該變量內容在序列化後沒法得到訪問 volatile修飾符 volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值. 當成員變量發生變化時,強迫線程將變化值回寫到共享內存.這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值.
運算符
算數運算符,關係運算符,位運算符,邏輯運算符,賦值運算符,其它運算符 條件運算符(?:),也稱爲三元運算符 variable x = (expression) ? value if true : value if false instanceOf運算符:該運算符用於操做對象實例,檢查該對象是不是一個特定類型(類類型或接口類型)
Java Number類
當須要使用數字的時候,咱們一般使用內置數據類型,如: byte,int,long,double等 然鵝,在實際開發中,咱們常常會遇到須要使用對象,而不是內置數據類型的情形, 爲了解決這個問題,Java語言爲每個內置數據類型提供了對應的包裝類 全部的包裝類(Integer、Long、Byte、Double、Float、Short)都是抽象類Number的子類 這種由 編譯器 特別支持的包裝稱爲 裝箱, 因此當內置數據類型被看成對象使用的時候, 編譯器會把內置類型裝箱爲包裝類.類似的,編譯器也可把一個對象拆箱爲內置類型. Number類屬於java.lang包 Number類的成員方法 xxxValue(): 將number對象轉換爲xxx數據類型的值並返回 compareTo(): 將number對象與參數比較 equals(): 判斷number對象是否與參數相等 valueOf(): 返回一個Integer對象指定的內置數據類型 toString(): 以字符串形式返回值 parseInt(): 將字符串解析爲int類型 abs(): 返回參數的絕對值 ceil(): 對整形變量向左取整,返回類型爲double型 floor(): 對整型變量向右取整。返回類型爲double類型 rint(): 返回與參數最接近的整數。返回類型爲double round(): 返回一個最接近的int、long型值 min(): 返回兩個參數中的最小值 max(): 返回兩個參數中的最大值 exp(): 返回天然數底數e的參數次方 log(): 返回參數的天然數底數的對數值 pow(): 返回第一個參數的第二個參數次方 sqrt(): 求參數的算術平方根 sin(): 求指定double類型參數的正弦值 cos(): 求指定double類型參數的餘弦值 tan(): 求指定double類型參數的正切值 random(): 返回一個隨機數
Java Character類
使用字符時,咱們一般使用的是內置數據類型cahr 而後在實際開發中,咱們常常會遇到須要使用對象,爲了解決這個問題,Java語言爲內置數據 類型char提供了包裝類Character類. Character類提供了一系列方法來操縱字符,可使用Character的構造方法建立一個Character類對象 Character ch = new Character('a'); Character類的成員方法 isLetter(): 是不是一個字母 isDigit(): 是不是一個數字字符 isWhitespace(): 是否一個空格 isUpperCase(): 是不是大寫字母 isLowerCase(): 是不是小寫字母 toUpperCase(): 指定字母的大寫形式 toLowerCase(): 指定字母的小寫形式 toString(): 返回字符的字符串形式,字符串的長度僅爲1 ...請參考java.lang.Character API規範
Java String類
在Java中字符串屬於對象, Java提供了String類來建立和操做字符串 建立字符串: String類有11種構造方法,這些方法提供不一樣的參數來初始化字符串 public class Main { public static void main(String[] args) { String greeting = "Hello world!"; char[] helloArray = {'h', 'e', 'l', 'l', 'o', '.'}; String helloString = new String(helloArray); System.out.println(helloString); } } 注意: String類是不可改變的,因此一旦建立了String對象,那它的值就沒法改變了. 若是須要對字符串作不少修改,那麼應該選擇使用StringBuffer & StringBuilder類 字符串長度 用於獲取有關對象的信息的方法稱爲訪問器方法 String類的一個訪問器方法是length()方法,它返回字符串對象包含的字符數 鏈接字符串 String類提供了鏈接兩個字符串的方法 String s3 = string1.concat(string2); //返回string1鏈接string2的新字符串 也可對字符串常量使用concat()方法: String s4 = "My name is".concat("Zara"); 更經常使用的是使用'+'操做符來鏈接字符串 String s5 = "Hello, " + " world" + "!"; 建立格式化字符串 String類使用靜態方法format()返回一個String對象而不是PrintStream對象 String類的靜態方法format()能用來建立可複用的格式化字符串,而不只僅是用於一次打印輸出 //例子: String fs; float floatVar = 9.8f; int intVar = 125; String stringVar = "Jimy"; fs = String.format("The value of the float variable is " + "%f, while the value of the integer" + "variable is %d, and the string " + "is %s", floatVar, intVar, stringVar); System.out.println(fs); //The value of the float variable is 9.800000, while the value of the integervariable is 125, and the string is Jimy String 方法 char charAt(int index): 返回指定索引處的 char 值 int compareTo(Object o): 把這個字符串和另外一個對象比較 int compareTo(String anotherString): 按字典順序比較兩個字符串 int compareToIgnoreCase(String str): 按字典順序比較兩個字符串,不考慮大小寫 String concat(String str): 將指定字符串鏈接到此字符串的結尾 boolean contentEquals(StringBuffer sb): 當且僅當字符串與指定的StringButter有相同順序的字符時候返回真 static String copyValueOf(char[] data): 返回指定數組中表示該字符序列的 String boolean endsWith(String suffix): 測試此字符串是否以指定的後綴結束 boolean equals(Object anObject): 將此字符串與指定的對象比較 boolean equalsIgnoreCase(String anotherString): 將此 String 與另外一個 String 比較,不考慮大小寫 byte[] getBytes(): 使用平臺的默認字符集將此 String 編碼爲 byte 序列,並將結果存儲到一個新的 byte 數組中 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): 將字符今後字符串複製到目標字符數組 int hashCode(): 返回此字符串的哈希碼 int indexOf(int ch): 返回指定字符在此字符串中第一次出現處的索引 int lastIndexOf(int ch): 返回指定字符在此字符串中最後一次出現處的索引 boolean matches(String regex): 告知此字符串是否匹配給定的正則表達式 boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len): 測試兩個字符串區域是否相等 String[] split(String regex): 根據給定正則表達式的匹配拆分此字符串 boolean startsWith(String prefix): 測試此字符串是否以指定的前綴開始 String substring(int beginIndex): 返回一個新的字符串,它是此字符串的一個子字符串 char[] toCharArray(): 將此字符串轉換爲一個新的字符數組 String toLowerCase(): 使用默認語言環境的規則將此 String 中的全部字符都轉換爲小寫 String toUpperCase(): 使用默認語言環境的規則將此 String 中的全部字符都轉換爲大寫 String trim(): 返回字符串的副本,忽略前導空白和尾部空白
Java StringBuffer和StringBuilder類
對字符串進行修改的時候,須要使用StringBuffer和StringBuilder類 和String類不一樣的是,StringBuffer和StringBuilder類的對象可以被屢次的修改,且不產生新的未使用對象 StringBuffer和StringBuilder類之間的最大不一樣在於StringBuilder的方法不是線程安全的(不能同步訪問) 因爲StringBuilder相較於StringBuffer有速度優點,大多數狀況下建議使用StringBuilder類. 然而在應用程序要求線程安全的狀況下,則必須使用StringBuffer類 //例子 public class Main { public static void main(String[] args) { StringBuffer sBuffer = new StringBuffer("test"); sBuffer.append(" String Buffer"); System.out.println(sBuffer); //test String Buffer } } StringBuffer 方法 public StringBuffer append(String s): 將指定的字符串追加到此字符序列 public StringBuffer reverse(): 將此字符序列用其反轉形式取代 public delete(int start, int end): 移除此序列的子字符串中的字符 public insert(int offset, int i): 將 int 參數的字符串表示形式插入此序列中 replace(int start, int end, String str): 使用給定 String 中的字符替換此序列的子字符串中的字符 ...
Java數組
用來存儲固定大小的同類型元素 double[] myList; //首選的聲明寫法 myList = new double[1024]; //建立數組 數組做爲函數的參數 數組能夠做爲參數傳遞給方法 數組做爲函數的返回值 public class Main { public static void printArray(double[] array){ for(int i = 0;i < array.length;i++){ System.out.println(array[i] + " "); } } public static double[] reverse(double[] list){ double[] result = new double[list.length]; for(int i = 0, j = result.length - 1; i < list.length; i++, j--){ result[j] = list[i]; } return result; } public static void main(String[] args) { StringBuffer sBuffer = new StringBuffer("test"); sBuffer.append(" String Buffer"); System.out.println(sBuffer); //test String Buffer double[] myList = {1.9, 2.9, 3.4, 3.5}; //打印全部數組元素 for(int i = 0; i < myList.length; i++){ System.out.println(myList[i] + " "); } for(double ele:myList){ System.out.println(ele); } printArray(myList); //計算全部元素的總和 double total = 0; for(int i = 0;i < myList.length;i++){ total += myList[i]; } System.out.println("Total is " + total); //查找最大元素 double max = myList[0]; for(int i = 1;i < myList.length; i++){ if(myList[i] > max){ max = myList[i]; } } System.out.println("Max is " + max); double[] reverse = reverse(myList); printArray(reverse); } } Arrays類 java.util.Arrays類能方便地操做數組,它提供的全部方法都是靜態的. 1.給數組賦值: 經過fill方法 2.對數組排序: 通縮sort方法,按升序. 3.比較數組: 經過equals方法比較數組中元素值是否相等 4.查找數組元素: 經過binarySearch方法能對排序好的數組進行二分查找法操做 public static void fill(int[] a, int val) public static void sort(Object[] a) public static boolean equals(long[] a, long[] a2) public static int binarySearch(Object[] a, Object key)
Java日期時間
java.util包提供了Date類來封裝當前的日期和時間,Date類提供兩個構造函數來實例化Date對象 1.Date(): 使用當前日期和時間來初始化對象 2.Date(long millisec): 該參數從1970年一月一日起的微秒數 Date對象建立後,可調用下面的方法: boolean after(Date date): 若當調用此方法的Date對象在指定日期以後返回true,不然返回false boolean before(Date date): 若當調用此方法的Date對象在指定日期以前返回true,不然返回false Object clone(): 返回此對象的副本 int compareTo(Date date): 比較當調用此方法的Date對象和指定日期。二者相等時候返回0。調用對象在指定日期以前則返回負數。調用對象在指定日期以後則返回正數 int compareTo(Object obj): 若obj是Date類型則操做等同於compareTo(Date) 。不然它拋出ClassCastException boolean equals(Object date): 當調用此方法的Date對象和指定日期相等時候返回true,不然返回false long getTime(): 返回自 1970 年 1 月 1 日 00:00:00 GMT 以來此 Date 對象表示的毫秒數 int hashCode(): 返回此對象的哈希碼值 void setTime(long time): 用自1970年1月1日00:00:00 GMT之後time毫秒數設置時間和日期 String toString(): 轉換Date對象爲String表示形式,並返回該字符串 使用SimpleDateFormat格式化日期 import java.text.SimpleDateFormat; import java.util.Date; //時間日期專題 public class Main { public static void main(String[] args) { //初始化 Date 對象 Date date = new Date(); //使用toString()函數顯示日期時間 System.out.println(date.toString()); //Thu Jun 06 17:13:04 CST 2019 //使用SimpleDateFormat格式化日期 SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); System.out.println("Current Date: " + ft.format(date)); //Current Date: 週四 2019.06.06 at 05:17:07 下午 CST } } 使用printf格式化日期 import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 使用toString()顯示日期和時間 String str = String.format("Current Date/Time : %tc", date ); System.out.printf(str); } } /---------------------------------------/ import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 使用toString()顯示日期和時間 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date); } } DateFormat格式化編碼 日期和時間轉換字符 解析字符串爲時間 SimpleDateFormat類有一些附加的方法,特別是parse(),它試圖按照給定的SimpleDateFormat對象的格式化存儲 來解析字符串 Java 休眠(sleep) 可讓程序休眠 Thread.sleep(5*60*10); 測量時間 long start = System.currentTimeMillis(); System.out.println(new Date() + "\n"); Thread.sleep(5*60*10); //休眠10秒,不許確 System.out.println(new Date() + "\n"); long end = System.currentTimeMillis(); long diff = end - start; System.out.println("Difference is :" + diff/1000); //秒 Calendar類 如何設置和獲取日期數據的特定部分,好比小時,日,或者分鐘? 使用Calendar類 Calendar類的功能要比Date類強大不少,並且實現方式上也比Date類要複雜一些 Calendar類是一個抽象類,在實際使用時實現特定的子類的對象,建立對象的過程對程序員來講時透明的 ,只需使用getInstance方法建立便可 Calendar c = Calendar.getInstance(); //默認是當前日期 GregorianCalendar類 Calendar類實現了公曆日曆,GregorianCalendar是Calendar類的一個具體實現 import java.util.Calendar; import java.util.GregorianCalendar; public class Main { public static void main(String[] args){ String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int year; //初始化Gregorian 日曆 //使用當前時間和日期 //默認爲本地時間和時區 GregorianCalendar gcalendar = new GregorianCalendar(); //顯示當前時間和日期的信息 System.out.print("Date: "); System.out.print(months[gcalendar.get(Calendar.MONTH)]); System.out.print(" "+ gcalendar.get(Calendar.DATE) + " "); System.out.println(year = gcalendar.get(Calendar.YEAR)); System.out.print("Time: "); System.out.print(gcalendar.get(Calendar.HOUR) + ":"); System.out.print(gcalendar.get(Calendar.MINUTE) + ":"); System.out.println(gcalendar.get(Calendar.SECOND)); //判斷當前年份是否爲潤年 if(gcalendar.isLeapYear(year)){ System.out.println("當前年份是潤年"); }else{ System.out.println("當前年份不是潤年"); } } }
JAVA方法
方法是解決一類問題的步驟的有序組合 方法包含於類和對象中 方法在程序中被建立,在其它地方被引用 方法的定義: 修飾符 返回值類型 方法名(參數類型 參數名) ... 方法體 ... return 返回值 main方法是被JVM調用 重載的方法必須具備不一樣的參數列表,不能僅僅依據修飾符或返回類型的不一樣來重載方法 構造方法: 全部的類都有構造方法,由於JAVA自動提供了一個默認構造方法,它把全部成員初始化爲0. 一旦你定義了本身的構造方法,默認構造方法就會失效 finalize()方法: JAVA容許定義這樣的方法,它在對象被垃圾收集器析構(回收)以前調用,用來清除回收對象 例如:可使用finalize()方法來確保一個對象打開的文件被關閉了. 在finalize()方法裏,必須指定在對象銷燬時候要執行的操做.
JAVA流、文件、IO
輸入流:表示從一個源讀取數據 輸出流: 表示向一個目標寫數據 讀取控制檯輸入: JAVA的控制檯輸入由System.in完成 爲了得到一個綁定到控制檯的字符流,能夠把System.in包裝在BufferedReader對象中來建立一個字符流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) BufferedReader對象建立後,咱們可使用read()方法從控制檯讀取一個字符,或者用readLine()方法來讀取一個字符串 //讀寫文件,一個流被定義爲一個數據序列,輸入流用於從源讀取數據,輸出流用於向目標寫數據 //Object---(OutputStream, InputStream) //OutputStream---(FilterOutputStream,FileOutputStream,ByteArrayOutputStream) //FilterOutputStream---(BufferedOutputStream, DataOutputStream, PrintStream) //InputStream---(ByteArrayInputStream,FileInputStream,FilterInputStream,StringBufferInputStream,SequenceInputStream) //FilterInputStream---(BufferedInputStream, DataInputStream, PushbackInputStream) //FileInputStream //該流用於從文件讀取數據,用關鍵字new來建立對象 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class Main { public static void main(String[] args) { try{ //建立輸入流對象來讀取文件 FileInputStream f = new FileInputStream("C:\\Users\\jasmintung\\meiju\\main.cpp"); File ff = new File("C:\\Users\\jasmintung\\meiju\\main.cpp"); //也可以使用一個文件對象來建立一個輸入輸出流對象來讀取文件 InputStream fs = new FileInputStream(ff); }catch(FileNotFoundException ex) { System.out.println(ex); } } } 建立了InputStream對象,就可使用下面方法來讀取流或進行其它的操做 1:public void close() throws IOException{} 關閉此文件輸入流並釋放與此流有關的全部系統資源。拋出IOException異常。 2:protected void finalize()throws IOException {} 這個方法清除與該文件的鏈接。確保在再也不引用文件輸入流時調用其 close 方法。拋出IOException異常 3:public int read(int r)throws IOException{} 這個方法從InputStream對象讀取指定字節的數據。返回爲整數值。返回下一字節數據,若是已經到結尾則返回-1 4:public int read(byte[] r) throws IOException{} 這個方法從輸入流讀取r.length長度的字節。返回讀取的字節數。若是是文件結尾則返回-1 5:public int available() throws IOException{} 返回下一次對此輸入流調用的方法能夠不受阻塞地今後輸入流讀取的字節數。返回一個整數值 //FileOutputStream 該類用來建立一個文件並向文件中寫數據 //FileReader,FileWriter類 //JAVA中的目錄 建立目錄: mkdir(),mkdirs() //讀取目錄: 一個目錄其實就是一個File對象,它包含其它文件或文件夾 若是建立一個File對象而且它是一個目錄,那麼調用isDirectory()方法會返回true 可經過調用該對象上的list()方法,來提取它包含的文件和文件夾的列表 import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/tmp"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "Directory of " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }
JAVA異常處理
異常是程序中的一些錯誤,但並非全部的錯誤都是異常,而且錯誤有時候能夠避免 異常發生的緣由有不少,一般包含一下幾大類: 1.用戶輸入了非法數據 2.要打開的文件不存在 3.網絡通訊時鏈接中斷,或者JVM內存溢出 要理解Java異常處理是如何工做的,你須要掌握如下三種類型的異常: 檢查性異常: 最具表明的檢查性異常是用戶錯誤或問題引發的異常,這是程序員沒法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。 運行時異常: 運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常能夠在編譯時被忽略。 錯誤: 錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中一般被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的 Exception類的層次: 全部的異常類都是從java.lang.Exception類繼承的子類 Exception類是Throwable類的子類. 除了Exception類外,Throwable還有一個子類Error. 在Java內置類中,有大部分經常使用檢查性和非檢查性異常 Java 語言定義了一些異常類在java.lang標準包中 因爲java.lang包是默認加載到全部的Java程序的,因此大部分從運行時異常類繼承而來的異常均可以直接使用 捕獲異常: 使用try和catch關鍵字能夠捕獲異常. 多重捕獲塊 一個try代碼塊後面跟隨多個catch代碼塊的狀況叫多重捕獲 throws/throw關鍵字 若是一個方法沒有捕獲一個檢查性異常,那麼該方法必須使用throws關鍵字類聲明 throws關鍵字放在方法簽名的尾部 import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } //Remainder of class definition } finally關鍵字 finally關鍵字用來建立在try代碼塊後面執行的代碼塊 不管是否發生異常,finally代碼塊中的代碼總會被執行 在finally代碼塊中,能夠運行清理類型等收尾善後性質的語句 finally代碼塊出如今catch代碼塊最後 try{ // 程序代碼 }catch(異常類型1 異常的變量名1){ // 程序代碼 }catch(異常類型2 異常的變量名2){ // 程序代碼 }finally{ // 程序代碼 } 聲明自定義異常 在java中能夠自定義異常 注意: 1.全部異常都必須是Throwable的子類 2.若是但願寫一個檢查性異常類,則須要繼承Exception類 3.若是想寫一個運行時異常,那麼須要繼承RuntimeException類 例如: class MyException extends Exception{ // } 一個異常類和其它任何類同樣,包含有變量和方法 如何使用自定義的異常類: // 文件名InsufficientFundsException.java import java.io.*; public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } } // 文件名稱 CheckingAccount.java import java.io.*; public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } } //文件名稱 BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } } } 通用異常 在java中定義了兩種類型的異常和錯誤 1.JVM異常: 由JVM拋出的異常或錯誤.如:NullPointerException類, ArrayIndexOutOfBoundsException類,ClassCastException類 2.程序級異常: 由程序或者API程序拋出的異常 例如IllegalArgumentException類,IllegalStateException類
JAVA ByteArrayInputStream類
字節數組輸入流在內存中建立一個字節數組緩衝區,從輸入流讀取的數據保存在該字節數組緩衝區. 用法: ByteArrayInputStream bArray = new ByteArrayInputStream(byte[] a); ByteArrayInputStream bArray = new ByteArrayInputStream(byte[] a, int off, int len); 成功建立字節數組流對象後,可用如下方法對流進行讀操做或其它操做: 1.public int read(): 今後輸入流中讀取下一個數據字節 2.public int read(byte[] r, int off, int len): 將最多 len 個數據字節今後輸入流讀入字節數組 3.public int available(): 返回可不發生阻塞地今後輸入流讀取的字節數 4.public void mark(int read): 設置流中的當前標記位置 5.public long skip(long n): 今後輸入流中跳過 n 個輸入字節 例子: import java.io.*; public class ByteStreamTest { public static void main(String args[])throws IOException { ByteArrayOutputStream bOutput = new ByteArrayOutputStream(12); while( bOutput.size()!= 10 ) { // 獲取用戶輸入值 bOutput.write(System.in.read()); } byte b [] = bOutput.toByteArray(); System.out.println("Print the content"); for(int x= 0 ; x < b.length; x++) { // 打印字符 System.out.print((char)b[x] + " "); } System.out.println(" "); int c; ByteArrayInputStream bInput = new ByteArrayInputStream(b); System.out.println("Converting characters to Upper case " ); for(int y = 0 ; y < 1; y++ ) { while(( c= bInput.read())!= -1) { System.out.println(Character.toUpperCase((char)c)); } bInput.reset(); } } }
JAVA DataInputStream類
數據輸入流容許應用程序以與機器無關方式從底層輸入流中讀取基本JAVA數據類型 用法: DataInputStream dis = DataInputStream(InputStream in); 方法: 1.public final int read(byte[] r, int off, int len)throws IOException 從所包含的輸入流中將 len 個字節讀入一個字節數組中。若是len爲-1,則返回已讀字節數 2.Public final int read(byte [] b)throws IOException 從所包含的輸入流中讀取必定數量的字節,並將它們存儲到緩衝區數組 b 中 3.public final Boolean readBooolean()throws IOException, public final byte readByte()throws IOException, public final short readShort()throws IOException public final Int readInt()throws IOException 從輸入流中讀取字節,返回輸入流中兩個字節做爲對應的基本數據類型返回值 4.public String readLine() throws IOException 從輸入流中讀取下一文本行 例子: DataInputStream和DataOutputStream的使用,該例從文本文件test.txt中讀取5行,並轉換成大寫字母,最後保存在另外一個文件test1.txt中 import java.io.*; public class Test{ public static void main(String args[])throws IOException{ DataInputStream d = new DataInputStream(new FileInputStream("test.txt")); DataOutputStream out = new DataOutputStream(new FileOutputStream("test1.txt")); String count; while((count = d.readLine()) != null){ String u = count.toUpperCase(); System.out.println(u); out.writeBytes(u + " ,"); } d.close(); out.close(); } }
JAVA ByteArrayOutputStream 類
字節數組輸出流在內存中建立一個字節數組緩衝區,全部發送到輸出流的數據保存在該字節數組緩衝區中 用法: OutputStream bOut = new ByteArrayOutputStream(); OutputStream bOut = new ByteArrayOutputStream(int a) 方法: 1.public void reset() 將此字節數組輸出流的 count 字段重置爲零,從而丟棄輸出流中目前已累積的全部數據輸出 2.public byte[] toByteArray() 建立一個新分配的字節數組。數組的大小和當前輸出流的大小,內容是當前輸出流的拷貝 3.public String toString() 將緩衝區的內容轉換爲字符串,根據平臺的默認字符編碼將字節轉換成字符 4.public void write(int w) 將指定的字節寫入此字節數組輸出流 5.public void write(byte []b, int of, int len) 將指定字節數組中從偏移量 off 開始的 len 個字節寫入此字節數組輸出流 6.public void writeTo(OutputStream outSt) 將此字節數組輸出流的所有內容寫入到指定的輸出流參數中
JAVA DataoutputStream 類
數據輸出流容許應用程序以與機器無關方式將Java基本數據類型寫到底層輸出流 用法: DataOutputStream out = DataOutputStream(OutputStream out); 方法: 1.public final void write(byte[] w, int off, int len)throws IOException 將指定字節數組中從偏移量 off 開始的 len 個字節寫入此字節數組輸出流 2.Public final int write(byte [] b)throws IOException 將指定的字節寫入此字節數組輸出流 3.public final void writeBooolean()throws IOException, public final void writeByte()throws IOException, public final void writeShort()throws IOException, public final void writeInt()throws IOException 這些方法將指定的基本數據類型以字節的方式寫入到輸出流 4.Public void flush()throws IOException 刷新此輸出流並強制寫出全部緩衝的輸出字節 5.public final void writeBytes(String s) throws IOException 將字符串以字節序列寫入到底層的輸出流,字符串中每一個字符都按順序寫入,並丟棄其高八位
JAVA File類
JAVA文件類以抽象的方式表明文件名和目錄路徑名.該類主要用於文件和目錄的建立,文件的查找和文件的刪除等 File對象表明磁盤中實際存在的文件和目錄 用法: File(File parent, String child); File(String pathname); File(String parent, String child); File(URI uri); 方法: 1 public String getName() 返回由此抽象路徑名錶示的文件或目錄的名稱。 2 public String getParent()、 返回此抽象路徑名的父路徑名的路徑名字符串,若是此路徑名沒有指定父目錄,則返回 null。 3 public File getParentFile() 返回此抽象路徑名的父路徑名的抽象路徑名,若是此路徑名沒有指定父目錄,則返回 null。 4 public String getPath() 將此抽象路徑名轉換爲一個路徑名字符串。 5 public boolean isAbsolute() 測試此抽象路徑名是否爲絕對路徑名。 6 public String getAbsolutePath() 返回抽象路徑名的絕對路徑名字符串。 7 public boolean canRead() 測試應用程序是否能夠讀取此抽象路徑名錶示的文件。 8 public boolean canWrite() 測試應用程序是否能夠修改此抽象路徑名錶示的文件。 9 public boolean exists() 測試此抽象路徑名錶示的文件或目錄是否存在。 10 public boolean isDirectory() 測試此抽象路徑名錶示的文件是不是一個目錄。 11 public boolean isFile() 測試此抽象路徑名錶示的文件是不是一個標準文件。 12 public long lastModified() 返回此抽象路徑名錶示的文件最後一次被修改的時間。 13 public long length() 返回由此抽象路徑名錶示的文件的長度。 14 public boolean createNewFile() throws IOException 當且僅當不存在具備此抽象路徑名指定的名稱的文件時,原子地建立由此抽象路徑名指定的一個新的空文件。 15 public boolean delete() 刪除此抽象路徑名錶示的文件或目錄。 16 public void deleteOnExit() 在虛擬機終止時,請求刪除此抽象路徑名錶示的文件或目錄。 17 public String[] list() 返回由此抽象路徑名所表示的目錄中的文件和目錄的名稱所組成字符串數組。 18 public String[] list(FilenameFilter filter) 返回由包含在目錄中的文件和目錄的名稱所組成的字符串數組,這一目錄是經過知足指定過濾器的抽象路徑名來表示的。 19 public File[] listFiles() 返回一個抽象路徑名數組,這些路徑名錶示此抽象路徑名所表示目錄中的文件。 20 public File[] listFiles(FileFilter filter) 返回表示此抽象路徑名所表示目錄中的文件和目錄的抽象路徑名數組,這些路徑名知足特定過濾器。 21 public boolean mkdir() 建立此抽象路徑名指定的目錄。 22 public boolean mkdirs() 建立此抽象路徑名指定的目錄,包括建立必需但不存在的父目錄。 23 public boolean renameTo(File dest) 從新命名此抽象路徑名錶示的文件。 24 public boolean setLastModified(long time) 設置由此抽象路徑名所指定的文件或目錄的最後一次修改時間。 25 public boolean setReadOnly() 標記此抽象路徑名指定的文件或目錄,以便只可對其進行讀操做。 26 public static File createTempFile(String prefix, String suffix, File directory) throws IOException 在指定目錄中建立一個新的空文件,使用給定的前綴和後綴字符串生成其名稱。 27 public static File createTempFile(String prefix, String suffix) throws IOException 在默認臨時文件目錄中建立一個空文件,使用給定前綴和後綴生成其名稱。 28 public int compareTo(File pathname) 按字母順序比較兩個抽象路徑名。 29 public int compareTo(Object o) 按字母順序比較抽象路徑名與給定對象。 30 public boolean equals(Object obj) 測試此抽象路徑名與給定對象是否相等。 31 public String toString() 返回此抽象路徑名的路徑名字符串 例子: import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/java"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "Directory of " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }
JAVA FileReader類
FileReader類從InputStreamReader類繼承而來,該類按字符讀取流中數據. 用法: FileReader(File file); FileReader(FileDescriptor fd); FileReader(String fileName; 方法: 1 public int read() throws IOException 讀取單個字符,返回一個int型變量表明讀取到的字符 2 public int read(char [] c, int offset, int len) 讀取字符到c數組,返回讀取到字符的個數 例子: import java.io.*; public class FileRead{ public static void main(String args[])throws IOException{ File file = new File("Hello1.txt"); // 建立文件 file.createNewFile(); // creates a FileWriter Object FileWriter writer = new FileWriter(file); // 向文件寫入內容 writer.write("This\n is\n an\n example\n"); writer.flush(); writer.close(); // 建立 FileReader 對象 FileReader fr = new FileReader(file); char [] a = new char[50]; fr.read(a); // 讀取數組中的內容 for(char c : a) System.out.print(c); // 一個一個打印字符 fr.close(); } }
JAVA FileWriter類
FileWriter類從OutputStreamReader類繼承而來。該類按字符向流中寫入數據 用法: FileWriter(File file); FileWriter(File file, boolean append); FileWriter(FileDescriptor fd); FileWriter(String fileName, boolean append); 方法: 1 public void write(int c) throws IOException 寫入單個字符c。 2 public void write(char [] c, int offset, int len) 寫入字符數組中開始爲offset長度爲len的某一部分。 3 public void write(String s, int offset, int len) 寫入字符串中開始爲offset長度爲len的某一部分。
Java 繼承
JAVA中,類的繼承是單一繼承,一個子類只能擁有一個父類 繼承中最常使用的兩個關鍵字: extends 和 implements 這兩個關鍵字的使用決定了一個對象和另外一個對象是不是IS-A(是一個)關係 經過使用這兩個關鍵字,咱們能實現一個對象獲取另外一個對象的屬性 全部JAVA的類均是由java.lang.Object類繼承而來的,因此Object是全部類的祖先類, 除了Object外,全部類必須有一個父類 // A.java public class A { private int i; protected int j; public void func() { } } // B.java public class B extends A { } B由A繼承而來的, B是A的子類. 而A是Object的子類, 這裏能夠不顯示地聲明 做爲子類,B的實例擁有A全部的成員變量,但對於 private 的成員變量B卻沒有訪問權限,這保障了A的封裝性 什麼是IS-A關係? 一個對象是另外一個對象的一個分類 public class Animal{ } public class Mammal extends Animal{ } public class Reptile extends Animal{ } public class Dog extends Mammal{ } 分析以上示例中的IS-A關係,以下: Mammal IS-A Animal Reptile IS-A Animal Dog IS-A Mammal 所以 : Dog IS-A Animal 經過使用關鍵字 extends,子類能夠繼承父類的除private屬性外全部的屬性. 咱們經過使用 instanceof 操做符,可以肯定Mammal IS-A Animal(返回true or false) public class Dog extends Mammal{ public static void main(String args[]){ Animal a = new Animal(); Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); //true System.out.println(d instanceof Mammal); //true System.out.println(d instanceof Animal); //true } } implements 關鍵字 使用在類繼承接口的狀況下.這種狀況下不能使用extends HAS-A 關係 表明類和它的成員之間的從屬關係.有助於代碼的重用和減小代碼的錯誤 例子: public class Vehicle{} public class Speed{} public class Van extends Vehicle{ private Speed sp; } Van類和Speed類是HAS-A關係(Van有一個Speed),這樣就不用將Speed類的所有代碼粘貼到Van類中了 而且Speed類也能夠重複利用於多個應用程序 JAVA只支持單繼承(繼承基本類和抽象類),可是咱們能夠用接口來實現(多繼承接口來實現) public class Apple extends Fruit implements Fruit1, Fruit2{ } 通常咱們繼承基本類和抽象類用 extends 關鍵字,實現接口類的繼承用 implements 關鍵字
JAVA重寫Override與重載Overload
重寫是子類對父類的容許訪問的方法的實現過程進行從新編寫,返回值和形參不能改變 重寫的好處在於子類能夠根據需求,定義特定於本身的行爲 也就是說子類可以根據須要實現父類的方法 例子: class Animal{ public void move(){ System.out.println("動物能夠移動"); } } class Dog extends Animal{ public void move(){ System.out.println("dog can run and walk"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); Animal b = new Dog(); //Dog對象 a.move(); //執行 Animal 類的方法 b.moev(); //執行 Dog 類的方法 } } 在上面的例子中能夠看到,儘管b屬於Animal類型,可是它運行的是Dog類的move方法。 這是因爲在編譯階段,只是檢查參數的引用類型。 然而在運行時,Java虛擬機(JVM)指定對象的類型而且運行該對象的方法。 所以在上面的例子中,之因此能編譯成功,是由於Animal類中存在move方法,然而運行時,運行的是特定對象的方法 思考例子: class Animal{ public void move(){ System.out.println("動物能夠移動"); } } class Dog extends Animal{ public void move(){ System.out.println("狗能夠跑和走"); } public void bark(){ System.out.println("狗能夠吠叫"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 對象 Animal b = new Dog(); // Dog 對象 a.move();// 執行 Animal 類的方法 b.move();//執行 Dog 類的方法 b.bark(); } } 運行結果: TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); 該程序將拋出一個編譯錯誤,由於b的引用類型Animal沒有bark方法 方寫重寫的規則 參數列表必須徹底與被重寫方法的相同; 返回類型必須徹底與被重寫方法的返回類型相同; 訪問權限不能比父類中被重寫的方法的訪問權限更高。例如:若是父類的一個方法被聲明爲public,那麼在子類中重寫該方法就不能聲明爲protected。 父類的成員方法只能被它的子類重寫。 聲明爲 final 的方法不能被重寫。 聲明爲 static 的方法不能被重寫,可是可以被再次聲明。 若是一個方法不能被繼承,那麼該方法不能被重寫。 子類和父類在同一個包中,那麼子類能夠重寫父類全部方法,除了聲明爲 private 和 final 的方法。 子類和父類不在同一個包中,那麼子類只可以重寫父類的聲明爲 public 和 protected 的非 final 方法。 重寫的方法可以拋出任何非強制異常,不管被重寫的方法是否拋出異常。可是,重寫的方法不能拋出新的強制性異常,或者比被重寫方法聲明的更普遍的強制性異常,反之則能夠。 構造方法不能被重寫。 若是不能繼承一個方法,則不能重寫這個方法 Super關鍵字的使用 當須要在子類中調用父類的被重寫方法時,要使用super關鍵字 class Animal{ public void move(){ System.out.println("anmial can move"); } } class Dog extends Animall{ public void move(){ super.move(); //調用 super類的方法 System.out.println("dog can run and walk"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); b.move(); } } 重載(Overload) 重載(overloading) 是在一個類裏面, 方法名字相同, 而參數不一樣.返回類型呢?能夠相同也能夠不一樣 重載規則: 被重載的方法必須改變參數列表; 被重載的方法能夠改變返回類型; 被重載的方法能夠改變訪問修飾符; 被重載的方法能夠聲明新的或更廣的檢查異常; 方法可以在同一個類中或者在一個子類中被重載 例子: public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //如下兩個參數類型順序不一樣 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); } 重寫與重載之間的區別 區別點 重載方法 重寫方法 參數列表 必須修改 必定不能修改 返回類型 能夠修改 必定不能修改 異常 能夠修改 能夠減小或刪除,必定不能拋出新的或者更廣的異常 訪問 能夠修改 必定不能作更嚴格的限制(能夠下降限制)
JAVA多態
多態,是同一個行爲具備多個不一樣表現形式或形態的能力 好比咱們說"寵物"這個對象,它就有不少不一樣的表達或實現,好比有小貓、小狗、蜥蜴等等。 那麼我到寵物店說"請給我一隻寵物",服務員給我小貓、小狗或者蜥蜴均可以,咱們就說"寵物"這個對象就具有多態性 例子: public interface Vegetarian{} public class Animal{} public class Deer extends Animal implements Vegetarian{} 此時,Deer類具備多重繼承,具備多態性 一個 Deer IS-A(是一個) Animal 一個 Deer IS-A(是一個) Vegetarian 一個 Deer IS-A(是一個) Deer 一個 Deer IS-A(是一個)Object 在JAVA中,全部的對象都具備多態性. 訪問一個對象的惟一方法是: 經過引用型變量 引用型變量只能有一種類型,一旦被聲明,引用型變量的類型就不能被改變了 引用型變量不只可以被重置爲其它對象,前提是這些對象沒有被聲明爲final. 還能夠引用和它類型相同的或者相兼容的對象.它能夠聲明爲類類型或者接口類型 當咱們將引用變量應用於Deer對象的引用時,下面的聲明時合法的: Deer d = new Deer(); Animal a = d; Vegetarian v = d; Object o = d; 全部的引用型變量d,a,v,o都指向堆中相同的Deer對象 虛方法(能夠理解爲C++中的虛函數) 當子類對象調用重載的方法時,調用的是子類的方法,而不是父類中被重載的方法 想要調用父類中被重載的方法,必須使用關鍵字super 例子(仔細看): /* 文件名 : Employee.java */ public class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } } /* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; //Annual salary public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Within mailCheck of Salary class "); System.out.println("Mailing check to " + getName() + " with salary " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } } /* 文件名 : VirtualDemo.java */ public class VirtualDemo { public static void main(String [] args) { Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00); Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00); System.out.println("Call mailCheck using Salary reference --"); s.mailCheck(); System.out.println("\n Call mailCheck using Employee reference--"); e.mailCheck(); } } 運行結果: Constructing an Employee Constructing an Employee Call mailCheck using Salary reference -- Within mailCheck of Salary class Mailing check to Mohd Mohtashim with salary 3600.0 Call mailCheck using Employee reference-- Within mailCheck of Salary class Mailing check to John Adams with salary 2400.0 例子中,咱們實例化了兩個Salary對象。一個使用Salary引用s,另外一個使用Employee引用。 編譯時,編譯器檢查到mailCheck()方法在Salary類中的聲明。 在調用s.mailCheck()時,Java虛擬機(JVM)調用Salary類的mailCheck()方法。 由於e是Employee的引用,因此調用e的mailCheck()方法則有徹底不一樣的結果。 當編譯器檢查e.mailCheck()方法時,編譯器檢查到Employee類中的mailCheck()方法。 在編譯的時候,編譯器使用Employee類中的mailCheck()方法驗證該語句, 可是在運行的時候,Java虛擬機(JVM)調用的是Salary類中的mailCheck()方法。 該行爲被稱爲虛擬方法調用,該方法被稱爲虛擬方法。 Java中全部的方法都能以這種方式表現,藉此,重寫的方法能在運行時調用,無論編譯的時候源代碼中引用變量是什麼數據類型。
JAVA抽象類
在面向對象的概念中,全部的對象都是經過類來描繪的,可是反過來,並非全部的類都是用來描繪對象的, 若是一個類中沒有包含足夠的信息來描述一個具體的對象,這樣的類就是抽象類 抽象類除了不能實例化對象以外,類的其它功能依然存在,成員變量,成員方法和構造方法的訪問方式和普通類同樣 因爲抽象類不能實例化對象,因此抽象類必須被繼承,才能被使用.也就是由於這個緣由,一般在設計階段決定要不要設計抽象類 定義一個抽象類: /* 文件名 : Employee.java */ public abstract class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public double computePay() { System.out.println("Inside Employee computePay"); return 0.0; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number; } } 該Employee類沒有什麼不一樣,儘管該類是抽象類,可是它仍然有3個成員變量,7個成員方法和1個構造方法. 如今若是你嘗試以下的例子: /* 文件名 : AbstractDemo.java */ public class AbstractDemo { public static void main(String [] args) { /* 如下是不容許的,會引起錯誤 */ Employee e = new Employee("George W.", "Houston, TX", 43); System.out.println("\n Call mailCheck using Employee reference--"); e.mailCheck(); } } 當你嘗試編譯AbstractDemo類時,會產生以下錯誤: Employee.java:46: Employee is abstract; cannot be instantiated Employee e = new Employee("George W.", "Houston, TX", 43); ^ 1 error 繼承抽象類 /* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; //Annual salary public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Within mailCheck of Salary class "); System.out.println("Mailing check to " + getName() + " with salary " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } } 儘管咱們不能實例化一個Employee類的對象,可是若是咱們實例化一個Salary類對象,該對象將從Employee類繼承3個成員變量和7個成員方法 抽象方法 若是想設計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現由它的子類肯定, 那麼能夠在父類中聲明該方法爲抽象方法 Abstract 關鍵詞一樣能夠用來聲明抽象方法,抽象方法只包含一個方法名,而沒有方法體 抽象方法沒有定義,方法名後面直接跟一個分號,而不是花括號 public abstract class Employee { private String name; private String address; private int number; public abstract double computePay(); //其他代碼 } 聲明抽象方法會形成如下兩個結果 1.若是一個類包含抽象方法,那麼該類必須是抽象類 2.任何子類必須重寫該類的抽象方法,或者聲明自身爲抽象類 繼承抽象方法的子類必須重載該方法.不然,該子類也必須聲明爲抽象類. 最終,必須有子類實現該抽象類方法 若是Salary類繼承了Employee類,那麼它必須實現computePay()方法 /* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; // Annual salary public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } //其他代碼 }
JAVA封裝(Encapsulation)
防止該類的代碼和數據被外部類定義的代碼隨機訪問 要訪問該類的代碼和數據,必須經過嚴格的接口控制 封裝最主要的功能在於咱們能修改本身的實現代碼,而不用修改那些調用咱們代碼的程序片斷 適當的封裝可讓程式碼更容易理解與維護. 例子: /* 文件名: EncapTest.java */ public class EncapTest{ private String name; private String idNum; private int age; public int getAge(){ return age; } public String getName(){ return name; } public String getIdNum(){ return idNum; } public void setAge( int newAge){ age = newAge; } public void setName(String newName){ name = newName; } public void setIdNum( String newId){ idNum = newId; } } 以上實例中public方法是外部類訪問該類成員變量的入口
JAVA接口
在java編程中是一個抽象類型,是抽象方法的集合.接口一般以interface來聲明. 一個類經過繼承接口的方式,從而來繼承接口的抽象方法 接口並非類, 類描述對象的屬性和方法,接口則包含要類實現的方法. 除非實現接口的類是抽象類,不然該類要定義接口中的全部方法 接口與類類似點: 一個接口能夠有多個方法。 接口文件保存在.java結尾的文件中,文件名使用接口名。 接口的字節碼文件保存在.class結尾的文件中。 接口相應的字節碼文件必須在與包名稱相匹配的目錄結構中。 接口與類的區別: 接口不能用於實例化對象。 接口沒有構造方法。 接口中全部的方法必須是抽象方法。 接口不能包含成員變量,除了static和final變量。 接口不是被類繼承了,而是要被類實現。 接口支持多重繼承。 接口的聲明: [可見度] interface 接口名稱 [extends 其餘的類名] { // 聲明變量 // 抽象方法 } /* 文件名 : NameOfInterface.java */ import java.lang.*; //引入包 public interface NameOfInterface { //任何類型 final, static 字段 //抽象方法 } 接口有如下特性: 接口是隱式抽象的,當聲明一個接口的時候,沒必要使用abstract關鍵字。 接口中每個方法也是隱式抽象的,聲明時一樣不須要abstract關鍵子。 接口中的方法都是公有的 接口的實現 當類實現接口的時候,類要實現接口中全部的方法。不然,類必須聲明爲抽象的類 ... implements 接口名稱[, 其餘接口, 其餘接口..., ...] ... 例子: /* 文件名 : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } } 接口的繼承 一個接口能繼承另外一個接口,和類之間的繼承方式比較類似.接口的繼承使用extends關鍵字,子接口繼承父接口的方法 // 文件名: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } // 文件名: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } // 文件名: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); } Hockey接口本身聲明瞭四個方法,從Sports接口繼承了兩個方法,這樣,實現Hockey接口的類須要實現六個方法。 類似的,實現Football接口的類須要實現五個方法,其中兩個來自於Sports接口 接口的多重繼承 在接口的多重繼承中extends關鍵字只須要使用一次,在其後跟着繼承接口 public interface Hockey extends Sports, Event 標記接口 最經常使用的繼承接口是沒有包含任何方法的接口 標識接口是沒有任何方法和屬性的接口.它僅僅代表它的類屬於一個特定的類型,供其餘代碼來測試容許作一些事情 標識接口做用:簡單形象的說就是給某個對象打個標(蓋個戳),使對象擁有某個或某些特權 例如:java.awt.event包中的MouseListener接口繼承的java.util.EventListener接口定義以下 package java.util; public interface EventListener {} 沒有任何方法的接口被稱爲標記接口。標記接口主要用於如下兩種目的: 1.創建一個公共的父接口: 正如EventListener接口,這是由幾十個其餘接口擴展的Java API, 你可使用一個標記接口來創建一組接口的父接口。例如:當一個接口繼承了EventListener接口, Java虛擬機(JVM)就知道該接口將要被用於一個事件的代理方案。 2.向一個類添加數據類型: 這種狀況是標記接口最初的目的,實現標記接口的類不須要定義任何接口方法(由於標記接口根本就沒有方法), 可是該類經過多態性變成一個接口類型
JAVA包
爲了更好的組織類,JAVA提供了包機制,用於區別類名的命名空間 包的做用: 1.把功能類似或相關的類或接口組織在同一個包中,方便類的查找和使用 2.如同文件夾同樣,包也採用樹形目錄的存儲方式.同一個包中的類名字是不一樣的, 不一樣的包中的類的名字是能夠相同的,當同時調用兩個不一樣包中相同類名的類時, 應該加上包名加以區別.包可避免名字衝突 3.包限定了訪問權限,擁有包訪問權限的類才能訪問某個包中類 包語句的語法格式: package pkg1[. pkg2...] 建立包 包聲明應該放在源文件的第一行,每一個源文件只能有一個包聲明,這個文件中的每一個類型都應用於它 若是一個源文件中沒有使用包聲明,那麼其中的類,函數,枚舉,註釋等將被放在一個無名的包(unnamed package)中. /* 文件名: Animal.java */ package animals; interface Animal { public void eat(); public void travel(); } package animals; /* 文件名 : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } } import關鍵字 爲了可以使用某一個包的成員,咱們須要在java程序中明確導入該包.使用"import"語句可完成此功能 在 java 源文件中 import 語句應位於 package 語句以後,全部類的定義以前,能夠沒有,也能夠有多條,其語法格式爲 import package1[.package2…].(classname|*); 若是在一個包中,一個類想要使用本包中的另外一個類,那麼該包名能夠省略 幾種導入包的寫法: 1.payroll.Employee 2.import payroll.*; 3.import payroll.Employee; 類文件中能夠包含任意數量的import聲明.import聲明必須在包聲明以後,類聲明以前 package的目錄結構 管理java中文件的一種簡單方式: 將類、接口等類型的源碼放在一個文本中,這個文件的名字就是這個類型的名字,並以.java做爲擴展名 接下來,把源文件放在一個目錄中,這個目錄要對應類所在包的名字 一般,一個公司使用它互聯網域名的顛倒形式來做爲它的包名.例如:互聯網域名是apple.com,全部的包名都以com.apple開頭. 包名中的每個部分對應一個子目錄 例如:這個公司有一個com.apple.computers的包,這個包包含一個叫作Dell.java的源文件,那麼相應的,應該有以下面的一連串子目錄: ....\com\apple\computers\Dell.java 編譯的時候,編譯器爲包中定義的每一個類、接口等類型各建立一個不一樣的輸出文件,輸出文件的名字就是這個類型的名字,並加上.class做爲擴展後綴。 例如: // 文件名: Dell.java package com.apple.computers; public class Dell{ } class Ups{ } 用-d選項來編譯這個文件: $javac -d . Dell.java 這樣會像下面這樣放置編譯了的文件: .\com\apple\computers\Dell.class.\com\apple\computers\Ups.class 編譯以後的.class文件應該和.java源文件同樣,它們放置的目錄應該跟包的名字對應起來。可是,並不要求.class文件的路徑跟相應的.java的路徑同樣。 你能夠分開來安排源碼和類的目錄: <path-one>\sources\com\apple\computers\Dell.java <path-two>\classes\com\apple\computers\Dell.class 這樣,你能夠將你的類目錄分享給其餘的編程人員,而不用透露本身的源碼。用這種方法管理源碼和類文件可讓編譯器和java虛擬機(JVM)能夠找到你程序中使用的全部類型。 類目錄的絕對路徑叫作class path。設置在系統變量CLASSPATH中。編譯器和java虛擬機經過將package名字加到class path後來構造.class文件的路徑。 <path- two>\classes是class path,package名字是com.apple.computers,而編譯器和JVM會在 <path-two>\classes\com\apple\compters中找.class文件。 一個class path可能會包含好幾個路徑。多路徑應該用分隔符分開。默認狀況下,編譯器和JVM查找當前目錄。JAR文件按包含Java平臺相關的類,因此他們的目錄默認放在了class path中 設置CLASSPATH系統變量 用下面的命令顯示當前的CLASSPATH變量: Windows平臺(DOS 命令行下)-> C:\> set CLASSPATH UNIX平臺(Bourne shell下)-> % echo $CLASSPATH 刪除當前CLASSPATH變量內容: Windows平臺(DOS 命令行下)-> C:\> set CLASSPATH= UNIX平臺(Bourne shell下)-> % unset CLASSPATH; export CLASSPATH 設置CLASSPATH變量: Windows平臺(DOS 命令行下)-> set CLASSPATH=C:\users\jack\java\classes UNIX平臺(Bourne shell下)-> % CLASSPATH=/home/jack/java/classes; export CLASSPATH
JAVA Enumeration接口
Enumeration接口中定義了一些方法,經過這些方法能夠枚舉對象集合中的元素 這種傳統接口已被迭代器取代,雖然Enumeration還未被丟棄,但現代代碼中不多使用了. 它還使用在諸如Vector和Properties這些傳統類所定義的方法中,除此以外,還用在一些API類 例子: import java.util.Vector; import java.util.Enumeration; public class EnumerationTester { public static void main(String args[]) { Enumeration days; Vector dayNames = new Vector(); dayNames.add("Sunday"); dayNames.add("Monday"); dayNames.add("Tuesday"); dayNames.add("Wednesday"); dayNames.add("Thursday"); dayNames.add("Friday"); dayNames.add("Saturday"); days = dayNames.elements(); while (days.hasMoreElements()){ System.out.println(days.nextElement()); } } } 運行結果: Sunday Monday Tuesday Wednesday Thursday Friday Saturday
JAVA Bitset類
一個Bitset類建立一種特殊類型的數組來保存位值.BitSet中數組大小會隨須要增長.這和位向量(vector of bits)比較相似 方法: 不少,直接看網址:https://code.ziqiangxuetang.com/java/java-bitset-class.html 例子: import java.util.BitSet; public class BitSetDemo { public static void main(String args[]) { BitSet bits1 = new BitSet(16); BitSet bits2 = new BitSet(16); // set some bits for(int i=0; i<16; i++) { if((i%2) == 0) bits1.set(i); if((i%5) != 0) bits2.set(i); } System.out.println("Initial pattern in bits1: "); System.out.println(bits1); System.out.println("\nInitial pattern in bits2: "); System.out.println(bits2); // AND bits bits2.and(bits1); System.out.println("\nbits2 AND bits1: "); System.out.println(bits2); // OR bits bits2.or(bits1); System.out.println("\nbits2 OR bits1: "); System.out.println(bits2); // XOR bits bits2.xor(bits1); System.out.println("\nbits2 XOR bits1: "); System.out.println(bits2); } } 以上實例編譯運行結果以下: Initial pattern in bits1: {0, 2, 4, 6, 8, 10, 12, 14} Initial pattern in bits2: {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14} bits2 AND bits1: {2, 4, 6, 8, 12, 14} bits2 OR bits1: {0, 2, 4, 6, 8, 10, 12, 14} bits2 XOR bits1: {}
JAVA Vector類
Vector類實現了一個動態數組.和ArrayList類似 Vector時同步訪問的 Vector包含了許多傳統的方法,這些方法不屬於集合框架 Vector主要用在事先不知道數組的大小,或者只是須要一個能夠改變大小的數組的狀況 方法: 不少,看網址:https://code.ziqiangxuetang.com/java/java-vector-class.html 例子: import java.util.*; public class VectorDemo { public static void main(String args[]) { // initial size is 3, increment is 2 Vector v = new Vector(3, 2); System.out.println("Initial size: " + v.size()); System.out.println("Initial capacity: " + v.capacity()); v.addElement(new Integer(1)); v.addElement(new Integer(2)); v.addElement(new Integer(3)); v.addElement(new Integer(4)); System.out.println("Capacity after four additions: " + v.capacity()); v.addElement(new Double(5.45)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Double(6.08)); v.addElement(new Integer(7)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Float(9.4)); v.addElement(new Integer(10)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Integer(11)); v.addElement(new Integer(12)); System.out.println("First element: " + (Integer)v.firstElement()); System.out.println("Last element: " + (Integer)v.lastElement()); if(v.contains(new Integer(3))) System.out.println("Vector contains 3."); // enumerate the elements in the vector. Enumeration vEnum = v.elements(); System.out.println("\nElements in vector:"); while(vEnum.hasMoreElements()) System.out.print(vEnum.nextElement() + " "); System.out.println(); } }
Java Stack類
棧時Vector的一個子類,它實現了一個標準的後進先出的棧 堆棧只定義了默認構造函數,用來建立一個空棧.堆棧除了包括由Vector定義的全部方法,也定義了本身的一些方法 例子: import java.util.*; public class StackDemo { static void showpush(Stack st, int a) { st.push(new Integer(a)); System.out.println("push(" + a + ")"); System.out.println("stack: " + st); } static void showpop(Stack st) { System.out.print("pop -> "); Integer a = (Integer) st.pop(); System.out.println(a); System.out.println("stack: " + st); } public static void main(String args[]) { Stack st = new Stack(); System.out.println("stack: " + st); showpush(st, 42); showpush(st, 66); showpush(st, 99); showpop(st); showpop(st); showpop(st); try { showpop(st); } catch (EmptyStackException e) { System.out.println("empty stack"); } } } 運行結果: stack: [ ] push(42) stack: [42] push(66) stack: [42, 66] push(99) stack: [42, 66, 99] pop -> 99 stack: [42, 66] pop -> 66 stack: [42] pop -> 42 stack: [ ] pop -> empty stack
JAVA Dictionary 類
Dictionary 類是一個抽象類,用來存儲鍵/值對,做用和Map類類似 給出鍵和值,你就能夠將值存儲在 Dictionary 對象中,一旦該值被存儲,就能夠經過它的鍵來獲取它. Dictionary 類已通過時了.在實際開發中,可實現Map 接口 來獲取鍵/值的存儲功能
JAVA Map 接口
Map 接口中鍵和值一一映射.可經過鍵來獲取值 給定一個鍵和一個值,你能夠將該值存儲在一個Map對象. 以後,你能夠經過鍵來訪問對應的值。 當訪問的值不存在的時候,方法就會拋出一個NoSuchElementException異常. 當對象的類型和Map裏元素類型不兼容的時候,就會拋出一個 ClassCastException異常。 當在不容許使用Null對象的Map中使用Null對象,會拋出一個NullPointerException 異常。 當嘗試修改一個只讀的Map時,會拋出一個UnsupportedOperationException異常。 方法: https://code.ziqiangxuetang.com/java/java-map-interface.html 例子: import java.util.*; public class CollectionsDemo { public static void main(String[] args) { Map m1 = new HashMap(); m1.put("Zara", "8"); m1.put("Mahnaz", "31"); m1.put("Ayan", "12"); m1.put("Daisy", "14"); System.out.println(); System.out.println(" Map Elements"); System.out.print("\t" + m1); } } 運行結果: Map Elements {Mahnaz=31, Ayan=12, Daisy=14, Zara=8}
JAVA Hashtable 接口
Hashtable如今集成到了集合框架中,支持同步. Hashtable在哈希表中存儲鍵/值對,當使用一個哈希表,要指定用做鍵的對象,以及要連接到該鍵的值 而後,該鍵通過哈希處理,所獲得的散列碼被用做存儲在該表中值的索引 方法:https://code.ziqiangxuetang.com/java/java-hashtable-class.html 例子: import java.util.*; public class HashTableDemo { public static void main(String args[]) { // Create a hash map Hashtable balance = new Hashtable(); Enumeration names; String str; double bal; balance.put("Zara", new Double(3434.34)); balance.put("Mahnaz", new Double(123.22)); balance.put("Ayan", new Double(1378.00)); balance.put("Daisy", new Double(99.22)); balance.put("Qadir", new Double(-19.08)); // Show all balances in hash table. names = balance.keys(); while(names.hasMoreElements()) { str = (String) names.nextElement(); System.out.println(str + ": " + balance.get(str)); } System.out.println(); // Deposit 1,000 into Zara's account bal = ((Double)balance.get("Zara")).doubleValue(); balance.put("Zara", new Double(bal+1000)); System.out.println("Zara's new balance: " + balance.get("Zara")); } }
Java Properties 接口
Properties 繼承於 Hashtable.表示一個持久的屬性集.屬性列表中每一個鍵及其對應值都是一個字符串 Properties 類被許多Java類使用。例如,在獲取環境變量時它就做爲System.getProperties()方法的返回值 方法: https://code.ziqiangxuetang.com/java/java-properties-class.html 例子: import java.util.*; public class PropDemo { public static void main(String args[]) { Properties capitals = new Properties(); Set states; String str; capitals.put("Illinois", "Springfield"); capitals.put("Missouri", "Jefferson City"); capitals.put("Washington", "Olympia"); capitals.put("California", "Sacramento"); capitals.put("Indiana", "Indianapolis"); // Show all states and capitals in hashtable. states = capitals.keySet(); // get set-view of keys Iterator itr = states.iterator(); while(itr.hasNext()) { str = (String) itr.next(); System.out.println("The capital of " + str + " is " + capitals.getProperty(str) + "."); } System.out.println(); // look for state not in list -- specify default str = capitals.getProperty("Florida", "Not Found"); System.out.println("The capital of Florida is " + str + "."); } }