Lambda表達式:
Lambda表達式是Java8之后的新特性
Lambda表達式是函數式編程
Java-->面向對象語言 block代碼塊(閉包) 函數式編程(接近於面向過程) --> 面向對象
什么是函數式編程?函數式編程(英語:functional programming)或稱函數程序設計,
又稱泛函編程,是一種編程范型,它將電腦運算視為數學上的函數(cos sin tan)計算,
並且避免使用程序狀態以及易變對象。函數編程語言最重要的基礎是λ演算(lambda calculus)。
而且λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值)。
ps:λ這個符號可以在搜狗輸入法的符號中顯示
而在面向對象編程中,面向對象程序設計(英語:Object-oriented programming,縮寫:OOP)
是種具有對象概念的程序編程范型,同時也是一種程序開發的方法。它可能包含數據、屬性、代碼與方法。
對象則指的是類的實例。它將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟件的重用性、
靈活性和擴展性,對象里的程序可以訪問及經常修改對象相關連的數據。在面向對象程序編程里,
計算機程序會被設計成彼此相關的對象。
Lambda表達式能干什么
將接口的實現方式重匿名內部類的形式簡化為了一個函數式表達式方式
簡化接口實現
語法:
(形參參數) -> 表達式 或{方法體};
ps:
Lambds表達式就是實現了當前接口中的方法及簡
void show();
() -> {System.out.println("我是Lambda表達式")};
1.形參列表
形參列表允許省略參數類型,若形參列表中只有一個參數,形參列表的原括號也可以省略
ps:形參列表 對應的是 接口中所需要實現方法的 形參列表
void show(int a, int b);
void display(int c);
(int a,int b) -> {實現};
(int a) -> {實現};
a -> {實現};
2.箭頭(->)
必須是英文狀態下的符號 減號(-) + 大於號(>) 指向實現代碼塊
3.代碼塊:
若代碼塊只包含一條語句,Lambda表達式允許允許省略花括號
若Lambda表達式中只有一條return,可以省略return關鍵字
若Lambda表達式中有多條語句(實現方法的邏輯)不能省略大括號
ps:Java中Lambda表達式的結合需要和接口完成
Stream API --> 流式編程
看Lambda包Test類
/** * */ package com.qfedu.Day25.Lambda; import java.util.ArrayList; /** * Description: 實現Lambda表達式語法<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:Test.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class Test { public static void main(String[] args) { //void show(); InteFaceB b = () ->{ System.out.println("B接口中方法的實現"); }; b.showB(); //簡化版本 InteFaceB b1 = () -> System.out.println("B中接口的實現"); b1.showB(); //void show(int a); InteFaceC c = (int a) ->{ System.out.println("接口C中的方法:"+a); }; c.showC(10); //簡化版本 Lambda表達式會推斷接口提供方法的數據類型 InteFaceC c1 = (a) -> System.out.println("接口C中的方法:"+a); c1.showC(1); //ArrayList<Integer> array = new ArrayList<>(); InteFaceC c2 = a -> System.out.println("接口C中方法"+a); c2.showC(2); //void show(int a,int b) InteFaceD d = (int a, int bi) -> { System.out.println("接口D中的方法實現"+(a+bi)); }; //簡化版本 InteFaceD d1 = (a,bi) ->{ System.out.println("接口D中的方法實現"+(a+bi)); }; //多參數的()堅決不能省略 InteFaceD d2 = (a,bi) -> System.out.println("接口D中的方法實現"+(a+bi)); //InteFaceD d3 = (a,bi) -> a+bi; 經常看到 } }
Lambda表達式還能作為參數傳遞
看Lambda包TestDemo類
/** * */ package com.qfedu.Day25.Lambda; /** * Description: Lambds表達式作為參數傳遞<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo { public static void showInfosInteFaceB(InteFaceB b) { System.out.println("B接口"); b.showB(); } public static void showInfosInteFaceC(String message,InteFaceC c) { System.out.println("C接口"+message); c.showC(100); } public static void showInfosInteFaceD(int a,int b,InteFaceD d) { System.out.println("D接口"); d.showD(a,b); } public static void main(String[] args) { //函數也是一種數據類型 --> 引用數據類型 //通過一個變量來存當前函數的引用 //基本實現 // showInfosInteFaceB(()->System.out.println("可以作為參數傳遞")); // showInfosInteFaceC(c -> System.out.println("可以作為參數")); // showInfosInteFaceD((a,b) -> System.out.println("可以作為參數")); showInfosInteFaceC("接口C的實現方式", c-> System.out.println("實現")); showInfosInteFaceD(300,200,(a,b)->System.out.println("實現+"+(a+b))); } }
ps:Java8中若這個接口需要使Lambda表達式實現此時我們需要在這個接口上提供一個注解
@FunctionalInteFace
Lambda表達式引用全局變量和局部變量
看Lambda包TestDemo2類
/** * */ package com.qfedu.Day25.Lambda; /** * Description: Lambds表達式引用全局變量和局部變量<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo2.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo2 { static String ms1 = "Hello"; String ms2 = "World"; public static void main(String[] args) { VariableTest v = message -> { //引用全局變量 在Lambda中可以直接引用靜態全局變量 System.out.println(message + ms1); //若引用成員變量需要使用對象調用 System.out.println(message + new TestDemo2().ms2); }; v.sayMessage("Lambda表達式:"); final String ms3 = "Hello World"; VariableTest v1 = message ->{ //可以在Lambda表達式中直接調用局部變量 //局部內部類-->引用局部變量時候,這個局部變量需要是final修改 //匿名內部類是一個特殊的局部內部類 //Lambda表達式是代替匿名內部類使用以上推斷得出 //在Lambda表達式中使用局部變量最好使用final修飾 //雖然Java7之后可以不寫final只要引用默認修飾,但是還是建議書寫 System.out.println(message + ms3); }; } }
Lambda式表達式引用構造方法和方法引用
1.引用類方法
在函數式接口中定義的抽象方法,而方法的實現是觸發某個類方法實現此時我們就可以通過 :: 形式完成
看Lambda包TestDemo3
/** * */ package com.qfedu.Day25.Lambda; /** * Description: Lambda表達式引用類方法<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo3.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo3 { public static void main(String[] args) { //在Lambda表達式中引用靜態方法 //Lambda表達式中只有一個 return 可以省略不寫 // Converter c = (String str) ->{ // // return Integer.valueOf(str); // }; Converter c = str -> Integer.valueOf(str); Integer i = c.convert("69"); System.out.println(i); //若Lambda不是的調用的是類方法並且參數可以進行方法傳遞 // :: --> 需要有返回值 ,方法中有參數並可以應用到調用該方法,這個方法必須是靜態方法 Converter c2 = Integer::valueOf; Integer i2 = c.convert("72"); System.out.println(i2); } }
2.引用實例方法(成員方法)
在函數式接口中定義的抽象方法,而方法的實現是通過觸發某類類創建的來完成時我們就可以 通過 :: 形式完成
看Lambda包TestDemo4;
/** * */ package com.qfedu.Day25.Lambda; /** * Description: Lambda表達式引用成員方法<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo4.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo4 { public static void main(String[] args) { //在Lambda表達式中引用成員方法 ClassATest ca = message -> new A().show(message); ca.display("45"); //:: --> 沒有返回值, 接口中方法對參數也需要作用於調用方法中 ,當前對象 ClassATest ca2 = new A()::show; ca2.display("17"); } }
版本二:
在函數式接口中定義的抽象方法,而方法上的實現是通過抽象方法中特定的對象參數來完成我們可以通過 :: 形式完成
不過 :: 之前是當前對象的數據了類型,而非 new出一個對象
看Lambda包TestDemo5;
/** * */ package com.qfedu.Day25.Lambda; /** * Description: 版本二引用成員方法<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo5.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo5 { public static void main(String[] args) { SubString str1 = (str,begin,end) -> str.substring(begin, end); String val = str1.sub("I LOVE U", 2, 6); System.out.println(val); //如何將當前上面Lambda轉換為 :: //因為當前接口中給的你方法使用的是參數作為對象調用方法 //此時修改成 ::形式的時候就不能重新創建對象了,需要使用其對應的數據類型即可 SubString str2 = String::substring; System.out.println(str2.sub("I LOVE U", 2, 6)); } }
3.引用構造方法
在函數式接口中定義的抽閑方法,而該方法的實現是通通過new 來創建對象,此時我們就可以使用 :: 形式來完成
ps:固定形式 構建對象的類型 :: new;
看Lambda包TestDemo6;
/** * */ package com.qfedu.Day25.Lambda; /** * Description: Lambda表達式引用構造方法<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo6.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo6 { public static void main(String[] args) { ClassBTest cb = (name,age) -> new B(name,age); B b1 = cb.getInstance("張三", 18); System.out.println(b1); //比較特殊的使用方式 引用的構造方法 ClassBTest cb1 = B::new; B b2 = cb1.getInstance("李四", 20); System.out.println(b2); } }
總結:
在上面兩個案例中使用到了一個全新的形式 類或(對象) :: 靜態方法/成員方法
若在Lambda表達式中引用了靜態方法或成員方法時 只有一句話 ,可以使用 :: 形式進行簡化
:: 之前 是這個方法主要的調用發起者 類/對象
:: 之后 靜態方法/成員方法
ps:一定要主要 方法后面千萬不要傳入參數
調用方法的參數,會通過接口中方法的參數進行傳遞
Lambda表達式和匿名內部類的區別
1.匿名內部類可以為任意接口創建對象,不管接口中包含多少個抽象方法,只要匿名內部類實現所有方法即可
但是Lambda表達式只能為函數式接口創建對象(只能實現一個抽象方法)
2.匿名內部類可以為抽象類甚至是普通類創建對象
但是Lambda表達式只能為函數接口創建對象
3.匿名內內部類實現的抽象方法方法體允許調用接口定義默認(default)方法
但是Lambda表達式的實現是不允許調用默認方法的
Lambds的實際引用
看Lambda包TestDemo7;
/** * */ package com.qfedu.Day25.Lambda; import java.util.Arrays; import java.util.Comparator; import java.util.List; /** * Description: Lambda表達式的實際應用<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:TestDemo7.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class TestDemo7 { public static void main(String[] args) { String[] name = {"張三","李四","王五"}; List<String> players = Arrays.asList(name); //遍歷集合 for(String str : players) { System.out.println(str); } //就可以這樣寫 流式編程方法 players.forEach((player) -> System.out.println(player+";")); //最簡版本 players.forEach(System.out::println); new Thread(new Runnable() { @Override public void run() { System.out.println("Hello Lambda"); } }).start(); new Thread(()->System.out.println("Hello Lambda")).start();; Runnable ru = () -> System.out.println("Hello Lambda"); new Thread(ru).start(); //數組排序 Arrays.sort(name, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); //Lambda表達式 Comparator<String> sortByName = (String str1, String str2) ->{ return str1.compareTo(str2); }; Arrays.sort(name, sortByName); Arrays.sort(name, (str1,str2)->str1.compareTo(str2)); } }
ps:
1.需要記住形式為了Scala做准備
2.Lambda可以替換匿名內部類一次實現的方式
Lambda只能實現接口中一個抽方法.
注解:
Java5開始 Java支持對元數據的支持, 就是是Annotation(注解)
元數據: metadata描述數據的數據
注解:標簽 Annotation
所有的Annotation都是java.Lang.annotation.Annotation接口的子接口
所有Annotation是一種特殊的接口
回顧注解:
@Override -->重寫
@Deprecated --> 過時的
@SuppressWarings --> 壓制警告
既可以放在方法上,放在變量上,放在類或接口上
使用注解需要注意:必須有三個參與才有意義
1.有注解的本身
2.被放置的位置(類,屬性,方法,接口,參數上,包等等)
3.由第三方程序使用反射的手段賦予注解特殊的功能
Java5之前自帶注解
Java5中提供的
@Override --> 限定子類重寫父類的方法,只能在方法上
@Deprecated --> 標記當前方法已經過時,不推薦使用 只能用在方法上
@SuppressWarings --> 抑制編譯器發出多種警告
@SuppressWarings(value="all") 可以應用在方法,類,屬性上
Java7中提供了一個
@SafeVarargs 抑制堆污染
當方法使用可變參數和泛型參數,此時就會造成堆污染 Arrays.asList
Java8中提供一個
@FunctionalInteFace 函數式編程 -->所用在接口上
元注解:
描述注解的注解,用來限定注解可以貼在哪些程序元素上,還可以指定注解存在的周期
@Retention: 表示注解可以保存在哪一個代碼時期. 保存的時期的值,封裝在RetentionPolicy枚舉類中:
注意:一般的,自定義的注解,使用RUNTIME.(使用反射賦予注解功能)
SOUECE:注解只能存在於源文件中,一旦編譯,在字節碼中就消失了.
CLASS:(缺省),注解可以存在於源文件和字節碼文件中,一旦加載進JVM,在JVM中就消失了.
RUNTIME:注解可以存在於源文件,字節碼文件,JVM中.
@Target:表示注解可以貼在哪些位置(類,方法上,構造器上等等).
位置的常量封裝在ElementType枚舉類中:
ElementType.ANNOTATION_TYPE只能修飾Annotation
ElementType.CONSTRUCTOR只能修飾構造方法
ElementType.FIELD只能修飾字段(屬性),包括枚舉常量
ElementType.LOCAL_VARIABLE只能修飾局部變量
ElementType.METHOD只能修飾方法
ElementType.PACKAGE只能修飾包(極少使用)
ElementType.PARAMETER只能修飾參數
ElementType.TYPE只能修飾類,接口,枚舉
實現自己的注解:
語法格式:
@interface
@Retention(設置注解存儲在的時間)
@Target(設置可以書寫注解的位置)
public @interface 注解名{
注解中的成員:
抽象方法 --> (屬性)
數據類型 方法名() default 默認值;
}
/** * */ package com.qfedu.Day25.Annotation; /** * Description: 描述類<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:Student.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ //若自定注解在注解中聲明抽象方法(屬性),使用注解時就需要給當前注解中的抽象方法(屬性)賦值 //若注解中使用了默認值,可以修改也可以不修改 @VIP(Value="A",age=19,favs = {"你好","呵呵"}) public class Student { private String name; private int age; } /** * */ package com.qfedu.Day25.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Description: 注解 <br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:VIP.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ @Retention(RetentionPolicy.RUNTIME) //注解的聲明周期就是源文件 ,編譯文件和 JVM中 @Target(ElementType.TYPE) //注解可以書寫的位置 類,方法和接口 public @interface VIP { // 抽象方法 --> 屬性看 //可以在注解中聲明的數據類型:基本數據類型, String Class 數組,枚舉,Annotation //聲明的同時就賦值,此時在外部寫書注解時就不需要賦值 String Value(); int age() default 19; String[] favs(); } /** * */ package com.qfedu.Day25.Annotation; import java.lang.annotation.Annotation; import java.util.Arrays; /** * Description: 如何取出注解中的值<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:VIPDemo.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class VIPDemo { public static void main(String[] args) { //1.獲取Student上的所有注解(反射) Annotation[] as = Student.class.getAnnotations(); for(int i = 0;i<as.length;i++) { System.out.println(as[i]); } //2.獲取Student真正的注解 //判斷當前類是否存在指定注解 if(Student.class.isAnnotationPresent(VIP.class)) { //獲取注解對象 VIP vip = Student.class.getAnnotation(VIP.class); String str = vip.Value(); String[] strs = vip.favs(); System.out.println(str); System.out.println(Arrays.toString(strs)); } } }
ps:Spring框架中--> 注解最多 --> 動態代理模式 --> 內省模式JavaBean和Map互轉
什么是測試:
軟件測試: 這是軟件生命周期中的一部分.--->好的軟件都不是開放出來的,都是測試出來的.黑盒測試: 軟件測試工程師.
黑盒測試也稱功能測試,它是通過測試來檢測每個功能是否都能正常使用。
在測試中,把程序看作一個不能打開的黑盒子,在完全不考慮程序內部結構和內部特性的情況下,在程序接口進行測試,它只檢查程序功能是否按照需求規格說明書的規定正常使用,程序是否能適當地接收輸入數據而產生正確的輸出信息。
黑盒測試着眼於程序外部結構,不考慮內部邏輯結構,主要針對軟件界面和軟件功能進行測試。
黑盒測試是以用戶的角度,從輸入數據與輸出數據的對應關系出發進行測試的。
很明顯,如果外部特性本身設計有問題或規格說明的規定有誤,用黑盒測試方法是發現不了的。
作用:
黑盒測試法注重於測試軟件的功能需求,主要試圖發現下列幾類錯誤。
功能不正確或遺漏;
界面錯誤;
輸入和輸出錯誤;
數據庫訪問錯誤;
性能錯誤;
初始化和終止錯誤等。
白盒測試:由軟件開放工程師來測試,只有自己開放的東西自己才知道是怎么運作的..
又稱結構測試、透明盒測試、邏輯驅動測試或基於代碼的測試。
它是按照程序內部的結構測試程序,通過測試來檢測產品內部動作是否按照設計規格說明書的規定正常進行,
檢驗程序中的每條通路是否都能按預定要求正確工作。 這一方法是把測試對象看作一個打開的盒子,測試人員依據程序內部邏輯結構相關信息,設計或選擇測試用例,對程序所有邏輯路徑進行測試,通過在不同點檢查程序的狀態,確定實際的狀態是否與預期的狀態一致。
白盒測試是一種測試用設計方法,盒子指的是被測試的軟件,白盒指的是盒子是可視的,你清楚盒子內部的東西以及里面是如何運作的。
"白盒"法全面了解程序內部邏輯結構、對所有邏輯路徑進行測試。測試者必須檢查程序的內部結構,從檢查程序的邏輯着手,得出測試數據。
單元測試(junit)屬於白盒測試.
ps:無論哪種測試,都需要給當前工程添加Junit-->jar
Junit3
Junit3是針對Java5之前的版本,沒有注解,需要按照規范的形式來書寫測試
遵守如下規則:
1.需要先將JUnit3添加到當前項目中
2.定義一個測試類,並讓該測試類繼承於TestCase類,測試的類型XXXTest
看Junit包Junit3Test
/** * */ package com.qfedu.Day25.Junit; import junit.framework.TestCase; /** * Description: 創建測試類<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:Junit3Test.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ //Junit使用的測試類必須繼承TestCase public class Junit3Test extends TestCase{ //定義測試方法 /* * 訪問權限修飾符必須是public * 無返回值 * 必須以test作為方法名的前綴 testXXX * 因為底層是用過反射來獲取當前方法的 * 所有異常都不要處理,一律拋出 * * 若需要執行測試類中的測試代碼 * 選中方法名 單機鼠標右鍵 選中 run as --> JUnit Test * * 在某些時候在測試完成之后 * 還對資源進行回收 * 重寫TestCase: * setUp() -->測試方法之前執行 * tearDown() --> 測試方法之后之后 */ /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ @Override protected void setUp() throws Exception { System.out.println("是在測試方法之前先執行"); } /* (non-Javadoc) * @see junit.framework.TestCase#tearDown() */ @Override protected void tearDown() throws Exception { System.out.println("是在測試方法執行之后執行"); } //保存 public void testSave()throws Exception{ System.out.println("測試代碼的操作了存儲"); } //刪除 public void testDelete()throws Exception{ System.out.println("測試代碼的操作了刪除"); } }
Junit4
Junit4是針對Java5之后的版本,使用的是注解,推薦
步驟
1.將Junit4添加到工程中
2.定義一個測試類,不在繼承TestCase類,類名必須是XXXTest
3.所有的測試方法使用的注解
看Junit包Junit4Test
/** * */ package com.qfedu.Day25.Junit; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * Description: Junit4測試類<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:Junit4Test.java <br/> * * @author 千鋒智哥 * @version : 1.0 */ public class Junit4Test { /* * Junit3中方法名必須是 testXXX * Junit4中不需要遵守這個規則,但是實際開發中保留這個書寫形式的 * 公有 無返回值 方法名保持和Junit3一致 testXXX 異常一律拋出 * ps:因為為了防止沖突刪除了Junit3這個測試jar包 * * 釋放資源 -->Junit3中 setUp tearDownJunit4完全不需要 * 使用 @Before @After釋放資源 * before --> 測試代碼 ---> After * 若測代碼使用BeforeClass 和 AfterClass 只會執行一次 * BeforeClass --> before --> 測試方法 --> After --> AfterClass * * * */ //若這是一個測試方法只需在方法的上面添加注解即可 //這兩注解必須使用靜態方法 只會執行一次 @BeforeClass public static void staticInit()throws Exception{ System.out.println("Begin..."); } @AfterClass public static void staticFinallzes()throws Exception{ System.out.println("end..."); } @Before public void init()throws Exception{ System.out.println("初始化....."); } @After public void finallzes()throws Exception{ System.out.println("銷毀...."); } @Test public void testSave() throws Exception{ System.out.println("Junit4下的測試方法"); } @Test public void testDelete() throws Exception{ System.out.println("Junit4下的測試方法"); } }
使用斷言:
一般而言,使用斷言是用來做單元測試使用
什么是斷言呢:期望的結果和真實結果是一樣的
期望值: 執行某個方法可以得到什么效果
實際值: 執行某個方法的到的實際效果
斷言成功: 實際值和期望值相同 ,顯示綠色
斷言失敗: 實際值和期望值不同 ,顯示紅色
①:Assert.assertEquals(message, expected, actual):比較的值,比較兩個對象值存儲的數據.
三個參數:
message: 斷言失敗的提示信息,斷言成功不會顯示.
expected: 期望值
actual: 真實值
若真實值和期望值想等,則斷言成功.--->綠條
②:Assert.assertSame(message, expected, actual):比較地址,是同一個對象
Assert.assertNotSame(message, expected, actual):斷言不是同一個對象
③:Assert.assertTrue(message, condition):斷言condition應該為TRUE.
④:Assert.assertFalse(message, condition):斷言condition應該為FALSE.
⑤:Assert.assertNull(message, object):斷言對象object為null.
⑥:Assert.assertNotNull(message, object):斷言對象object不為null.
⑦:@Test(expected=ArithmeticException.class)
期望該方法報錯,報錯ArithmeticException.
⑧:@Test(timeout=400)
期望該方法在400毫秒之內執行完成.
XML
學習到目前為止我們所知道的資源文件只有一個Properties文件 鍵值對 並且繼承於Hashtable
XML是一種可擴展標記語言和HTML類似
XML技術是W3C組織(WWW --> World Wide WEb)發布的目前通用的標准是2000年XML1.0規范
XML即可以作為一種配置文件存在,也可以作為數據傳輸文件
XML是一種通用的數據交換格式,許多系統都配備了XML格式文件
JSP文件檔組件XML格式過度
可以知道什么是XML,如何書寫正確的XML --> w3cschool ---> HTML CSS XML 菜鳥教程http://www.runoob.com/
看Info.xml
XML文件的語法:
XML文件的編碼需要正式一致,一般都是UTF-8
一個XML文件必須有一對根節點,節點名需要區分大小寫 節點中是不允許嵌套節點
<?xml version="1.0" encoding="UTF-8"?>
必須出現在文件的第一行而而且必須寫,用來表示文件是XML文件
節點中可以書寫子節點
標簽<Students>中是可以添加屬性
XML約束(了解)
可以對XML文件進行約束操作
dtd文件 schema 文件 --> xsd后綴名
XML中節點的創建
dtd約束文件:
<!ELEMENT contacts (linkman+)> contacts中必須有一個Linkeman節點 至少要有1個
+ 和 正則表達式是通用 ? 0或1 * 最少0個以上 :是一個1
<!ELEMENT linkman (name,email,address,group)> 在LinkeMan下需要出現以節點只能出現1個
<!ELEMENT name (#PCDATA)> p -> parse(解析) c-->Character(字符) --->解析字符串數據 只能傳入字符串
<!ELEMENT email (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!ELEMENT group (#PCDATA)>
看content2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 最后一個位置是路徑 因為文件已經在當前工程下了所以直接使用 -->
<!DOCTYPE contacts SYSTEM "constactsDtd.dtd">
<contacts>
<!-- 節點中是可以書寫屬性 -->
<linkman>
<name>Jack</name>
<email>ijack@sina.cn</email>
<address>北京</address>
<group>千鋒教育</group>
</linkman>
<linkman>
<name>Sparrow</name>
<email>sparrow@qq.com</email>
<address>北京</address>
<group>千鋒教育</group>
</linkman>
<linkman>
<name>Lily</name>
<email>lily@163.com</email>
<address>北京</address>
<group>千鋒教育</group>
</linkman>
</contacts>
schema 文件 --> xsd后綴名
看content.xml
<?xml version="1.0" encoding="UTF-8"?> <!--xmlns 約束來源 xmlns:xs 約束的依據 xs:schemaLocation 約束的位置 --> <contacts xmlns="http://qfedu.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://qfedu.com contactsSchema.xsd"> <linkman id="1" > <name>Jack</name> <email>ijack@sina.cn</email> <address>北京</address> <group>千鋒教育</group> </linkman> <linkman id="2"> <name>Sparrow</name> <email>sparrow@qq.com</email> <address>北京</address> <group>千鋒教育</group> </linkman> <linkman id="3"> <name>Lily</name> <email>lily@163.com</email> <address>北京</address> <group>千鋒教育</group> </linkman> </contacts>
Web概述:
原始年代1990-1992:
1990年,HTML標記語言的出現標志Web開發時代的到來.
B/S架構開始在之后的歲月中不斷的發展壯大,攻城略地蠶食傳統C/S的領域。
如同所有的新生事物一樣,在web的史前歲月,web的開發 技術在在html標記誕生后,
無論是在服務端還客戶端都緩慢的發展着,在相當長的一個時間內,它並未像今天這樣輝煌,
甚至於只是靜態的文本標識.
關鍵字:HTML
技術特性:靜態文本顯示,表現力和交互能力不足。(hao123)
封建諸侯年代1993-1996:
1993年,NCSA提出了CGI1.0草案。Web開發終於迎來了它的第二次重大飛躍,伴隨着CGI,
帶來Web的動態處理能力,CGI就是這個時代的國王。(服務器端動態生成內容)
1994年,PHP
1996年,ASP
關鍵字:CGI(Common Gateway Interface )(Perl&&C&&Python)
技術特性:實現了客戶端和服務器端的動態交互, 在程序代碼中寫html標記,
是面向過程的開發方式,用多進程運行
注:CGI是Web服務器端組件,都能產生Web動態頁面輸出
工業文明1996-1999:
1997年,Sun公司推出了Servlet規范。Java陣營終於迎來了自己的web英雄。
1998年JSP技術誕生,Servlet和JSP再加上JavaBean,
讓JavaWeb開發者同時擁有了類似CGI程序的集中處理功能和類似於PHP 的HTML嵌入功能,
此外,Java的運行編譯技術也大提高了Servlet和JSP的執行效率
1998年,Sun發布了EJB1.0標准
1999年,Sun正式發布了J2EE的第一個版本,緊接着,遵循J2EE,
為企業級應用提供支持平台的各類應用服務器爭先恐后的涌現出來(WebSphere,WebLogic,JBoss),
(同時2001微軟發布了ASP.NET技術)
查看HTTP數據規范格式:
請求消息的結構:
一個請求行、若干請求頭、以及實體內容,其中的一些請求頭和實體內容都是可選的,請求頭和實體內容之間要用空行隔開。
Request:
常見的請求頭:
<1>、Accept:瀏覽器可接受的MIME類型(Tomcat安裝目錄/conf/web.xml中查找)
MIME的英文全稱是"Multipurpose Internet Mail Extensions" 多用途互聯網郵件擴展,它是一個互聯網標准,在1992年最早應用於電子郵件系統,但后來也應用到瀏覽器。服務器會將它們發送的多媒體數據的類型告訴瀏覽器, 文件內容的類型:
MIME類型就是設定某種擴展名的文件用一種應用程序來打開的方式類型
<2>、Accept-Charset:告知服務器,客戶端支持哪種字符集
<3>、Accept-Encoding:瀏覽器能夠進行解碼的數據編碼方式
<4>、Accept-Language:瀏覽器支持的語言。
<5>、Referer:當前頁面由哪個頁面訪問過來的。
<6>、Content-Type:通知服務器,請求正文的MIME類型。
取值:application/x-www-form-urlencoded默認值
對應的是form表單的enctype屬性
<7>、Content-Length:請求正文的長度
<8>、If-Modified-Since:通知服務器,緩存的文件的最后修改時間。
<9>、User-Agent:通知服務器,瀏覽器類型.
<10>、Connection:表示是否需要持久連接。如果服務器看到這里的值為“Keep -Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久連接
<11>、Cookie:這是最重要的請求頭信息之一(會話有關)
響應消息的結構:
一個狀態行、若干響應頭、以及實體內容 ,其中的一些消息頭和實體內容都是可選的,響應頭和實體內容之間要用空行隔開。
Response:
常見的響應頭:
<1>、Location:制定轉發的地址。需與302/307響應碼一同使用
<2>、Server:告知客戶端服務器使用的容器類型
<3>、Content-Encoding:告知客戶端服務器發送的數據所采用的壓縮格式
<4>、Content-Length:告知客戶端正文的長度
<5>、Content-Type:告知客戶端正文的MIME類型
Conent-Type:text/html;charset=UTF-8
<6>、Refresh:定期刷新。還可以刷新到其他資源
Refresh:3;URL=otherurl
3秒后刷新到otherurl這個頁面
<7>、Content-Disposition:指示客戶端以下載的方式保存文件。
Content-Disposition:attachment;filename=2.jpg
<8>、Expires:網頁的有效時間。單位是毫秒(等於-1時表示頁面立即過期)
Cache-Control:no-cache
Pragma:no-cache
控制客戶端不要緩存
<9>、Set-Cookie:SS=Q0=5Lb_nQ; path=/search服務器端發送的Cookie(會話有關)
Get和Post
總結:
1.本質
Get是向服務器發索取數據的一種請求,而Post是向服務器提交數據的一種請求
2.服務器端獲取值的方法
get方式提交的數據,服務器端使用request.QueryString獲取變量的值
post方式提交的數據,服務器端使用request.Form獲取數據
3.安全性
get方式安全性低,post方式較安全。但是post方式執行效率要比get方式差一些。
4.機制
get是把參數數據隊列加到提交表單的action屬性所指的URL中,
如:http://www.xxx.com?sessonid=db23434&name=hongten&age=20。
在URl中,值和表單南日各個字段一一對應,並且這些在URl中對用戶來說是可見的,
即用戶時可以看到的。如:name=hongten。
post是通過HTTP post機制,
將表單內各個字段與其內容放置在HTML HEADER內一起傳送到action屬性所指的URL地址,
對於用戶來說,這是透明的。
5.大小
URL不存在參數上限的問題,HTTP協議規范沒有對URL長度進行限制。這個限制是特定的瀏覽器及服務器對它的限制。IE對URL長度的限制是2083字節(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於操作系統的支持。
理論上講,POST是沒有大小限制的,HTTP協議規范也沒有進行大小限制,說“POST數據量存在80K/100K的大小限制”是不准確的,POST數據是沒有限制的,起限制作用的是服務器的處理程序的處理能力。
get方式的安全性較post方式要差一些,所以,包含一些重要的信息的話,簡易使用post數據提交方式
在做查詢統計的時候,使用get方式要更好一些;而在做數據的添加,修改或刪除操作時,建議使用post數據提交方式
后記:
Java web中用到的技術
HTML:
超文本標記語言,標准通用標記語言下的一個應用。
“超文本”就是指頁面內可以包含圖片、鏈接,甚至音樂、程序等非文字元素。
超文本標記語言的結構包括“頭”部分(英語:Head)、和“主體”部分(英語:Body),
其中“頭”部提供關於網頁的信息,“主體”部分提供網頁的具體內容。
ps:靜態網頁 的組成
CSS:
層疊樣式表(英文全稱:Cascading Style Sheets)是一種用來表現HTML(標准通用標記語言的一個應用)
或XML(標准通用標記語言的一個子集)等文件樣式的計算機語言。CSS不僅可以靜態地修飾網頁,
還可以配合各種腳本語言動態地對網頁各元素進行格式化。
CSS 能夠對網頁中元素位置的排版進行像素級精確控制,支持幾乎所有的字體字號樣式,擁有對網頁對象和模型樣式編輯的能力。
ps:對靜態或動態網頁裝飾用的
JavaScript
JavaScript一種直譯式腳本語言,是一種動態類型、弱類型、基於原型的語言,內置支持類型。
它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用於客戶端的腳本語言,
最早是在HTML(標准通用標記語言下的一個應用)網頁上使用,用來給HTML網頁增加動態功能
ps:添加特效
Servlet
Servlet(Server Applet)是Java Servlet的簡稱,稱為小服務程序或服務連接器,
用Java編寫的服務器端程序,主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。
ps:讓網頁與服務器之間具備傳輸數據的能力
JSP
JSP全名為Java Server Pages,中文名叫java服務器頁面,其根本是一個簡化的Servlet設計
它是由Sun Microsystems公司倡導、許多公司參與一起建立的一種動態網頁技術標准。
JSP技術有點類似ASP技術,它是在傳統的網頁HTML(標准通用標記語言的子集)
文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP標記(tag),從而形成JSP文件,后綴名為(*.jsp)。
用JSP開發的Web應用是跨平台的,既能在Linux下運行,也能在其他操作系統上運行
ps:一種讓Servlet簡化的語言
AJAX
是一種用於創建更好更快以及交互性更強的Web應用程序的技術
ps:可以提高網頁和服務器之間的連接效率
JQuery
JQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之后又一個優秀的JavaScript代碼庫(或JavaScript框架)。
jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝JavaScript常用的功能代碼,
提供一種簡便的JavaScript設計模式,優化HTML文檔操作、事件處理、動畫設計和Ajax交互。
ps:加強版JavaScript
Bootstrap
Bootstrap是美國Twitter公司基於HTML、CSS、JavaScript 開發的簡潔、直觀、強悍的前端開發框架,使得 Web 開發更加快捷。
ps:讓HTML、CSS、JavaScript 更加便捷
框架(Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件實例間交互的方法;
另一種定義認為,框架是可被應用開發者定制的應用骨架。前者是從應用方面而后者是從目的方面給出的定義。
可以說,一個框架是一個可復用的設計構件,它規定了應用的體系結構,闡明了整個設計、協作構件之間的依賴關系、
責任分配和控制流程,表現為一組抽象類以及其實例之間協作的方法,它為構件復用提供了上下文(Context)關系。
因此構件庫的大規模重用也需要框架。
應用框架指的是實現了某應用領域通用完備功能(除去特殊應用的部分)的底層服務。
使用這種框架的編程人員可以在一個通用功能已經實現的基礎上開始具體的系統開發。
框架提供了所有應用期望的默認行為的類集合。具體的應用通過重寫子類(該子類屬於框架的默認行為)或組裝對象來支持應用專用的行為。
應用框架強調的是軟件的設計重用性和系統的可擴充性,以縮短大型應用軟件系統的開發周期,提高開發質量。
與傳統的基於類庫的面向對象重用技術比較,應用框架更注重於面向專業領域的軟件重用。應用框架具有領域相關性,
構件根據框架進行復合而生成可運行的系統。框架的粒度越大,其中包含的領域知識就更加完整。
框架,即framework。其實就是某種應用的半成品,就是一組組件,供你選用完成你自己的系統。
簡單說就是使用別人搭好的舞台,你來做表演。而且,框架一般是成熟的,不斷升級的軟件。
框架(Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件實例間交互的方法;
另一種定義認為,框架是可被應用開發者定制的應用骨架。前者是從應用方面而后者是從目的方面給出的定義。
可以說,一個框架是一個可復用的設計構件,它規定了應用的體系結構,闡明了整個設計、協作構件之間的依賴關系、責任分配和控制流程,
表現為一組抽象類以及其實例之間協作的方法,它為構件復用提供了上下文(Context)關系。因此構件庫的大規模重用也需要框架。
應用框架指的是實現了某應用領域通用完備功能(除去特殊應用的部分)的底層服務。
使用這種框架的編程人員可以在一個通用功能已經實現的基礎上開始具體的系統開發。
框架提供了所有應用期望的默認行為的類集合。
具體的應用通過重寫子類(該子類屬於框架的默認行為)或組裝對象來支持應用專用的行為。
應用框架強調的是軟件的設計重用性和系統的可擴充性,以縮短大型應用軟件系統的開發周期,
提高開發質量。與傳統的基於類庫的面向對象重用技術比較,應用框架更注重於面向專業領域的軟件重用。
應用框架具有領域相關性,構件根據框架進行復合而生成可運行的系統。框架的粒度越大,其中包含的領域知識就更加完整。
框架,即framework。其實就是某種應用的半成品,就是一組組件,供你選用完成你自己的系統。簡單說就是使用別人搭好的舞台,你來做表演。而且,框架一般是成熟的,不斷升級的軟件。
SSH 為 struts+spring+hibernate 的一個集成框架,是目前較流行的一種JAVA Web應用程序開源框架
Struts
Struts是一個基於Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技術來實現的。
由於Struts能充分滿足應用開發的需求,簡單易用,敏捷迅速,在過去的一年中頗受關注。
Struts把Servlet、JSP、自定義標簽和信息資源(message resources)整合到一個統一的框架中,
開發人員利用其進行開發時不用再自己編碼實現全套MVC模式,極大的節省了時間,所以說Struts是一個非常不錯的應用框架。
Spring
Spring是一個解決了許多在JavaEE開發中常見的問題的強大框架。
Spring提供了管理業務對象的一致方法並且鼓勵了注入對接口編程而不是對類編程的良好習慣。
Spring的架構基礎是基於使用JavaBean屬性的Inversion of Control容器。
然而,這僅僅是完整圖景中的一部分:Spring在使用IOC容器作為構建完關注所有架構層的完整解決方案方面是獨一無二的。
Spring提供了唯一的數據訪問抽象,包括簡單和有效率的JDBC框架,極大的改進了效率並且減少了可能的錯誤。
Spring的數據訪問架構還集成了Hibernate和其他O/R mapping解決方案。
Spring還提供了唯一的事務管理抽象,它能夠在各種底層事務管理技術,例如JTA或者JDBC事務提供一個一致的編程模型。
Spring提供了一個用標准Java語言編寫的AOP框架,它給POJOs提供了聲明式的事務管理和其他企業事務--如果你需要--還能實現你自己的aspects。
這個框架足夠強大,使得應用程序能夠拋開EJB的復雜性,同時享受着和傳統EJB相關的關鍵服務。
Spring還提供了可以和IoC容器集成的強大而靈活的MVC Web框架。
Hibernate
Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,
使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,
既可以在Java的客戶端程序實用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,
Hibernate可以在應用EJB的JavaEE架構中取代CMP,完成數據持久化的重任。
SSM為 Spring+SpringMVC+MyBatis的一個集成框架,是目前較流行的一種JAVA Web應用程序開源框架
Spring
Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,
由Rod Johnson 在其著作Expert One-On-One JavaEE Development and Design中闡述的部分理念和原型衍生而來。
它是為了解決企業應用開發的復雜性而創建的。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。
然而,Spring的用途不僅限於服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。
簡單來說,Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。
SpringMVC
Spring MVC屬於SpringFrameWork的后續產品,已經融合在Spring Web Flow里面。
Spring MVC 分離了控制器、模型對象、分派器以及處理程序對象的角色,這種分離讓它們更容易進行定制。
MyBatis
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。
MyBatis是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)MyBatis
消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。MyBatis 使用簡單的 XML或注解用於配置和原始映射,
將接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
