Java經典設計模式共有21中,分為三大類:創建型模式(5種)、結構型模式(7種)和行為型模式(11種)。
本文主要講行為型模式,創建型模式和結構型模式可以看博主的另外兩篇文章:[Java經典設計模式之五大創建型模式(附實例和詳解)](http://blog.csdn.net/u013142781/article/details/50816245)、[?Java經典設計模式之七大結構型模式(附實例和詳解)](http://blog.csdn.net/u013142781/article/details/50821155)。
行為型模式細分為如下11種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

接下來對11種行為型模式逐個進行介紹。
### 一、策略模式
策略模式定義了一系列算法,并將每個算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。需要設計一個接口,為一系列實現類提供統一的方法,多個實現類實現該接口,設計一個抽象類(可有可無,屬于輔助類,視實際需求是否添加),提供輔助函數。
首先統一接口:
~~~
package com.model.behaviour;
public interface ICalculator {
public int calculate(String exp);
}
~~~
輔助類:
~~~
package com.model.behaviour;
public abstract class AbstractCalculator {
public int[] split(String exp, String opt) {
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
~~~
三個實現類:
~~~
package com.model.behaviour;
public class Plus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp, "\\+");
return arrayInt[0] + arrayInt[1];
}
}
~~~
~~~
package com.model.behaviour;
public class Minus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp, "\\-");
return arrayInt[0] - arrayInt[1];
}
}
~~~
~~~
package com.model.behaviour;
public class Multiply extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\*");
return arrayInt[0]*arrayInt[1];
}
}
~~~
測試類:
~~~
package com.model.behaviour;
public class StrategyTest {
public static void main(String[] args) {
String exp = "8-2";
ICalculator cal = new Minus();
int result = cal.calculate(exp);
System.out.println(exp + "=" + result);
}
}
~~~
策略模式的決定權在用戶,系統本身提供不同算法的實現,新增或者刪除算法,對各種算法做封裝。因此,策略模式多用在算法決策系統中,外部用戶只需要決定用哪個算法即可。
### 二、模板方法模式
解釋一下模板方法模式,就是指:一個抽象類中,有一個主方法,再定義1…n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用。
就是在AbstractCalculator類中定義一個主方法calculate,calculate()調用spilt()等,Plus和Minus分別繼承AbstractCalculator類,通過對AbstractCalculator的調用實現對子類的調用,看下面的例子:
~~~
package com.model.behaviour;
public abstract class AbstractCalculator {
/*主方法,實現對本類其它方法的調用*/
public final int calculate(String exp,String opt){
int array[] = split(exp,opt);
return calculate(array[0],array[1]);
}
/*被子類重寫的方法*/
abstract public int calculate(int num1,int num2);
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
~~~
~~~
package com.model.behaviour;
public class Plus extends AbstractCalculator {
@Override
public int calculate(int num1,int num2) {
return num1 + num2;
}
}
~~~
~~~
package com.model.behaviour;
public class StrategyTest {
public static void main(String[] args) {
String exp = "8+8";
AbstractCalculator cal = new Plus();
int result = cal.calculate(exp, "\\+");
System.out.println(result);
}
}
~~~
### 三、觀察者模式
包括這個模式在內的接下來的四個模式,都是類和類之間的關系,不涉及到繼承。
觀察者模式很好理解,類似于郵件訂閱和RSS訂閱,當我們瀏覽一些博客或wiki時,經常會看到RSS圖標,就這的意思是,當你訂閱了該文章,如果后續有更新,會及時通知你。其實,簡單來講就一句話:當一個對象變化時,其它依賴該對象的對象都會收到通知,并且隨著變化!對象之間是一種一對多的關系。
~~~
package com.model.behaviour;
public interface Observer {
public void update();
}
~~~
~~~
package com.model.behaviour;
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
~~~
~~~
package com.model.behaviour;
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
~~~
~~~
package com.model.behaviour;
public interface Subject {
/*增加觀察者*/
public void add(Observer observer);
/*刪除觀察者*/
public void del(Observer observer);
/*通知所有的觀察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
~~~
~~~
package com.model.behaviour;
import java.util.Enumeration;
import java.util.Vector;
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
~~~
~~~
package com.model.behaviour;
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("update self!");
notifyObservers();
}
}
~~~
~~~
package com.model.behaviour;
public class ObserverTest {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
~~~
運行結果:
~~~
update self!
observer1 has received!
observer2 has received!
~~~
也許看完實例之后還是比較抽象,再將文字描述和代碼實例看一兩遍吧,然后結合工作中看哪些場景可以使用這種模式以加深理解。
### 四、迭代子模式
顧名思義,迭代器模式就是順序訪問聚集中的對象,一般來說,集合中非常常見,如果對集合類比較熟悉的話,理解本模式會十分輕松。這句話包含兩層意思:一是需要遍歷的對象,即聚集對象,二是迭代器對象,用于對聚集對象進行遍歷訪問。
具體來看看代碼實例:
~~~
package com.model.behaviour;
public interface Collection {
public Iterator iterator();
/* 取得集合元素 */
public Object get(int i);
/* 取得集合大小 */
public int size();
}
~~~
~~~
package com.model.behaviour;
public interface Iterator {
// 前移
public Object previous();
// 后移
public Object next();
public boolean hasNext();
// 取得第一個元素
public Object first();
}
~~~
~~~
package com.model.behaviour;
public class MyCollection implements Collection {
public String string[] = { "A", "B", "C", "D", "E" };
@Override
public Iterator iterator() {
return new MyIterator(this);
}
@Override
public Object get(int i) {
return string[i];
}
@Override
public int size() {
return string.length;
}
}
~~~
~~~
package com.model.behaviour;
public class MyIterator implements Iterator {
private Collection collection;
private int pos = -1;
public MyIterator(Collection collection){
this.collection = collection;
}
@Override
public Object previous() {
if(pos > 0){
pos--;
}
return collection.get(pos);
}
@Override
public Object next() {
if(pos<collection.size()-1){
pos++;
}
return collection.get(pos);
}
@Override
public boolean hasNext() {
if(pos<collection.size()-1){
return true;
}else{
return false;
}
}
@Override
public Object first() {
pos = 0;
return collection.get(pos);
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
Collection collection = new MyCollection();
Iterator it = (Iterator) collection.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
~~~
輸出結果:
~~~
A
B
C
D
E
~~~
此處我們貌似模擬了一個集合類的過程,感覺是不是很爽?其實JDK中各個類也都是這些基本的東西,加一些設計模式,再加一些優化放到一起的,只要我們把這些東西學會了,掌握好了,我們也可以寫出自己的集合類,甚至框架!
### 五、責任鏈模式
責任鏈模式,有多個對象,每個對象持有對下一個對象的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。但是發出者并不清楚到底最終那個對象會處理該請求,所以,責任鏈模式可以實現,在隱瞞客戶端的情況下,對系統進行動態的調整。
~~~
package com.model.behaviour;
public interface Handler {
public void operator();
}
~~~
~~~
package com.model.behaviour;
public abstract class AbstractHandler {
private Handler handler;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
~~~
~~~
package com.model.behaviour;
public class MyHandler extends AbstractHandler implements Handler {
private String name;
public MyHandler(String name) {
this.name = name;
}
@Override
public void operator() {
System.out.println(name + "deal!");
if (getHandler() != null) {
getHandler().operator();
}
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
MyHandler h1 = new MyHandler("h1");
MyHandler h2 = new MyHandler("h2");
MyHandler h3 = new MyHandler("h3");
h1.setHandler(h2);
h2.setHandler(h3);
h1.operator();
}
}
~~~
運行結果:
~~~
h1deal!
h2deal!
h3deal!
~~~
此處強調一點就是,鏈接上的請求可以是一條鏈,可以是一個樹,還可以是一個環,模式本身不約束這個,需要我們自己去實現,同時,在一個時刻,命令只允許由一個對象傳給另一個對象,而不允許傳給多個對象。
### 六、命令模式
命令模式很好理解,舉個例子,司令員下令讓士兵去干件事情,從整個事情的角度來考慮,司令員的作用是,發出口令,口令經過傳遞,傳到了士兵耳朵里,士兵去執行。這個過程好在,三者相互解耦,任何一方都不用去依賴其他人,只需要做好自己的事兒就行,司令員要的是結果,不會去關注到底士兵是怎么實現的。
~~~
package com.model.behaviour;
public interface Command {
public void exe();
}
~~~
~~~
package com.model.behaviour;
public class MyCommand implements Command {
private Receiver receiver;
public MyCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void exe() {
receiver.action();
}
}
~~~
~~~
package com.model.behaviour;
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
command.exe();
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command cmd = new MyCommand(receiver);
Invoker invoker = new Invoker(cmd);
invoker.action();
}
}
~~~
命令模式的目的就是達到命令的發出者和執行者之間解耦,實現請求和執行分開,熟悉Struts的同學應該知道,Struts其實就是一種將請求和呈現分離的技術,其中必然涉及命令模式的思想!
### 七、備忘錄模式
主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,個人覺得叫備份模式更形象些,通俗的講下:假設有原始類A,A中有各種屬性,A可以決定需要備份的屬性,備忘錄類B是用來存儲A的一些內部狀態,類C呢,就是一個用來存儲備忘錄的,且只能存儲,不能修改等操作。
~~~
package com.model.behaviour;
public class Original {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
public Memento createMemento(){
return new Memento(value);
}
public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
}
~~~
~~~
package com.model.behaviour;
public class Memento {
private String value;
public Memento(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
~~~
~~~
package com.model.behaviour;
public class Storage {
private Memento memento;
public Storage(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
// 創建原始類
Original origi = new Original("egg");
// 創建備忘錄
Storage storage = new Storage(origi.createMemento());
// 修改原始類的狀態
System.out.println("初始化狀態為:" + origi.getValue());
origi.setValue("niu");
System.out.println("修改后的狀態為:" + origi.getValue());
// 回復原始類的狀態
origi.restoreMemento(storage.getMemento());
System.out.println("恢復后的狀態為:" + origi.getValue());
}
}
~~~
輸出結果:
~~~
初始化狀態為:egg
修改后的狀態為:niu
恢復后的狀態為:egg
~~~
如果還不能理解,可以給Original類添加一個屬性name,然后其他類進行相應的修改試試。
### 八、狀態模式
核心思想就是:當對象的狀態改變時,同時改變其行為,很好理解!就拿QQ來說,有幾種狀態,在線、隱身、忙碌等,每個狀態對應不同的操作,而且你的好友也能看到你的狀態,所以,狀態模式就兩點:1、可以通過改變狀態來獲得不同的行為。2、你的好友能同時看到你的變化。
~~~
package com.model.behaviour;
public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void method1(){
System.out.println("execute the first opt!");
}
public void method2(){
System.out.println("execute the second opt!");
}
}
~~~
~~~
package com.model.behaviour;
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void method() {
System.out.println("狀態為:" + state.getValue());
if (state.getValue().equals("state1")) {
state.method1();
} else if (state.getValue().equals("state2")) {
state.method2();
}
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
State state = new State();
Context context = new Context(state);
//設置第一種狀態
state.setValue("state1");
context.method();
//設置第二種狀態
state.setValue("state2");
context.method();
}
}
~~~
運行結果:
~~~
狀態為:state1
execute the first opt!
狀態為:state2
execute the second opt!
~~~
根據這個特性,狀態模式在日常開發中用的挺多的,尤其是做網站的時候,我們有時希望根據對象的某一屬性,區別開他們的一些功能,比如說簡單的權限控制等。
### 九、訪問者模式
訪問者模式把數據結構和作用于結構上的操作解耦合,使得操作集合可相對自由地演化。訪問者模式適用于數據結構相對穩定算法又易變化的系統。因為訪問者模式使得算法操作增加變得容易。若系統數據結構對象易于變化,經常有新的數據對象增加進來,則不適合使用訪問者模式。訪問者模式的優點是增加操作很容易,因為增加操作意味著增加新的訪問者。訪問者模式將有關行為集中到一個訪問者對象中,其改變不影響系統數據結構。其缺點就是增加新的數據結構很困難。
訪問者模式算是最復雜也是最難以理解的一種模式了。它表示一個作用于某對象結構中的各元素的操作。它使你可以在不改變各元素類的前提下定義作用于這些元素的新操作。
涉及角色:
1.Visitor 抽象訪問者角色,為該對象結構中具體元素角色聲明一個訪問操作接口。該操作接口的名字和參數標識了發送訪問請求給具體訪問者的具體元素角色,這樣訪問者就可以通過該元素角色的特定接口直接訪問它。
2.ConcreteVisitor.具體訪問者角色,實現Visitor聲明的接口。
3.Element 定義一個接受訪問操作(accept()),它以一個訪問者(Visitor)作為參數。
4.ConcreteElement 具體元素,實現了抽象元素(Element)所定義的接受操作接口。
5.ObjectStructure 結構對象角色,這是使用訪問者模式必備的角色。它具備以下特性:能枚舉它的元素;可以提供一個高層接口以允許訪問者訪問它的元素;如有需要,可以設計成一個復合對象或者一個聚集(如一個列表或無序集合)。
~~~
abstract class Element
{
public abstract void accept(IVisitor visitor);
public abstract void doSomething();
}
~~~
~~~
class ConcreteElement1 extends Element{
public void doSomething(){
System.out.println("這是元素1");
}
public void accept(IVisitor visitor){
visitor.visit(this);
}
}
~~~
~~~
class ConcreteElement2 extends Element{
public void doSomething(){
System.out.println("這是元素2");
}
public void accept(IVisitor visitor){
visitor.visit(this);
}
}
~~~
~~~
interface IVisitor{
public void visit(ConcreteElement1el1);
public void visit(ConcreteElement2el2);
}
~~~
~~~
class Visitor implements IVisitor{
public void visit(ConcreteElement1 el1){
el1.doSomething();
}
public void visit(ConcreteElement2 el2){
el2.doSomething();
}
}
~~~
~~~
class ObjectStruture{
public static List<Element> getList(){
List<Element>list = new ArrayList<Element>();
Random ran = newRandom();
for(int i = 0 ; i < 10 ; i ++){
int a=ran.nextInt(100);
if(a>50){
list.add (newConcreteElement1());
}else{
list.add (newConcreteElement2());
}
}
return list;
}
}
~~~
~~~
public class Client{
public static void main (String[]args){
List<Element> list = ObjectStruture.getList();
for(Elemente:list){
e.accept(newVisitor());
}
}
}
~~~
### 十、中介者模式
中介者模式(Mediator):用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
舉例:在一個公司里面,有很多部門、員工(我們統稱他們互相為Colleague“同事”),為了完成一定的任務,“同事”之間肯定有許多需要互相配合、交流的過程。如果由各個“同事”頻繁地到處去與自己有關的“同事”溝通,這樣肯定會形成一個多對多的雜亂的聯系網絡而造成工作效率低下。
此時就需要一位專門的“中介者”給各個“同事”分配任務,以及統一跟進大家的進度并在“同事”之間實時地進行交互,保證“同事”之間必須的溝通交流。很明顯我們知道此時的“中介者”擔任了溝通“同事”彼此之間的重要角色了,“中介者”使得每個“同事”都變成一對一的聯系方式,減輕了每個“同事”的負擔,增強工作效率。
同事類族:
~~~
package com.model.behaviour;
public abstract class AbstractColleague {
protected AbstractMediator mediator;
/**既然有中介者,那么每個具體同事必然要與中介者有聯系,
* 否則就沒必要存在于 這個系統當中,這里的構造函數相當
* 于向該系統中注冊一個中介者,以取得聯系
*/
public AbstractColleague(AbstractMediator mediator) {
this.mediator = mediator;
}
// 在抽象同事類中添加用于與中介者取得聯系(即注冊)的方法
public void setMediator(AbstractMediator mediator) {
this.mediator = mediator;
}
}
~~~
~~~
//具體同事A
package com.model.behaviour;
public class ColleagueA extends AbstractColleague {
//每個具體同事都通過父類構造函數與中介者取得聯系
public ColleagueA(AbstractMediator mediator) {
super(mediator);
}
//每個具體同事必然有自己分內的事,沒必要與外界相關聯
public void self() {
System.out.println("同事A --> 做好自己分內的事情 ...");
}
//每個具體同事總有需要與外界交互的操作,通過中介者來處理這些邏輯并安排工作
public void out() {
System.out.println("同事A --> 請求同事B做好分內工作 ...");
super.mediator.execute("ColleagueB", "self");
}
}
~~~
~~~
//具體同事B
package com.model.behaviour;
public class ColleagueB extends AbstractColleague {
public ColleagueB(AbstractMediator mediator) {
super(mediator);
}
public void self() {
System.out.println("同事B --> 做好自己分內的事情 ...");
}
public void out() {
System.out.println("同事B --> 請求同事A做好分內工作 ...");
super.mediator.execute("ColleagueA", "self");
}
}
~~~
中介者類族:
~~~
package com.model.behaviour;
public abstract class AbstractMediator {
//中介者肯定需要保持有若干同事的聯系方式
protected Hashtable<String, AbstractColleague> colleagues = new Hashtable<String, AbstractColleague>();
//中介者可以動態地與某個同事建立聯系
public void addColleague(String name, AbstractColleague c) {
this.colleagues.put(name, c);
}
//中介者也可以動態地撤銷與某個同事的聯系
public void deleteColleague(String name) {
this.colleagues.remove(name);
}
//中介者必須具備在同事之間處理邏輯、分配任務、促進交流的操作
public abstract void execute(String name, String method);
}
~~~
~~~
//具體中介者
package com.model.behaviour;
public class Mediator extends AbstractMediator{
//中介者最重要的功能,來回奔波與各個同事之間
public void execute(String name, String method) {
if("self".equals(method)){ //各自做好分內事
if("ColleagueA".equals(name)) {
ColleagueA colleague = (ColleagueA)super.colleagues.get("ColleagueA");
colleague.self();
}else {
ColleagueB colleague = (ColleagueB)super.colleagues.get("ColleagueB");
colleague.self();
}
}else { //與其他同事合作
if("ColleagueA".equals(name)) {
ColleagueA colleague = (ColleagueA)super.colleagues.get("ColleagueA");
colleague.out();
}else {
ColleagueB colleague = (ColleagueB)super.colleagues.get("ColleagueB");
colleague.out();
}
}
}
}
~~~
測試類:
~~~
//測試類
package com.model.behaviour;
public class Client {
public static void main(String[] args) {
//創建一個中介者
AbstractMediator mediator = new Mediator();
//創建兩個同事
ColleagueA colleagueA = new ColleagueA(mediator);
ColleagueB colleagueB = new ColleagueB(mediator);
//中介者分別與每個同事建立聯系
mediator.addColleague("ColleagueA", colleagueA);
mediator.addColleague("ColleagueB", colleagueB);
//同事們開始工作
colleagueA.self();
colleagueA.out();
System.out.println("======================合作愉快,任務完成!\n");
colleagueB.self();
colleagueB.out();
System.out.println("======================合作愉快,任務完成!");
}
}
~~~
運行結果:
~~~
同事A --> 做好自己分內的事情 ...
同事A --> 請求同事B做好分內工作 ...
同事B --> 做好自己分內的事情 ...
======================合作愉快,任務完成!
同事B --> 做好自己分內的事情 ...
同事B --> 請求同事A做好分內工作 ...
同事A --> 做好自己分內的事情 ...
======================合作愉快,任務完成!
~~~
### 十一、解釋器模式
解釋器模式:給定一種語言,定義他的文法的一種表示,并定義一個解釋器,該解釋器使用該表示來解釋語言中句子。
解釋器模式是一個比較少用的模式。
~~~
package com.model.behaviour;
public class Context {
private int num1;
private int num2;
public Context(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}
~~~
~~~
package com.model.behaviour;
public interface Expression {
public int interpret(Context context);
}
~~~
~~~
package com.model.behaviour;
public class Minus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1()-context.getNum2();
}
}
~~~
~~~
package com.model.behaviour;
public class Plus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1()+context.getNum2();
}
}
~~~
~~~
package com.model.behaviour;
public class Test {
public static void main(String[] args) {
// 計算9+2-8的值
int result = new Minus().interpret((new Context(new Plus()
.interpret(new Context(9, 2)), 8)));
System.out.println(result);
}
}
~~~
注,本文參考了另外一位博主的文章,某些地方有結合自己的一些理解加以修改:?
[http://blog.csdn.net/zhangerqing/article/details/8194653](http://blog.csdn.net/zhangerqing/article/details/8194653)
- 前言
- Java生成中間logo的二維碼(還可以加上二維碼名稱哦)
- Java我的高效編程之常用函數
- AES加密解密&&SHA1、SHA加密&&MD5加密
- Java中synchronized的使用實例
- Java基礎之集合
- Java基礎之泛型
- Java基礎之枚舉妙用
- 那些年用過的一些前端框架
- 關于正則,那些年一直存在的疑惑解答(正則菜鳥不容錯過)
- 給pdf文件添加防偽水印logo(附工程源碼下載)
- SpringMVC+BUI實現文件上傳(附詳解,源碼下載)
- Java異常封裝(自己定義錯誤碼和描述,附源碼)
- javaweb異常提示信息統一處理(使用springmvc,附源碼)
- 關于Java,那些我心存疑惑的事(不斷更新中...)
- 深入Java虛擬機(1)——Java體系結構
- 深入Java虛擬機(2)——Java的平臺無關性
- 深入Java虛擬機(3)——安全
- 深入Java虛擬機(4)——網絡移動性
- Linux文件編輯命令詳細整理
- 阿里云服務器云數據庫免費體驗(Java Web詳細實例)
- 項目部署、配置、查錯常用到的Linux命令
- Shell腳本了解
- Ajax原理學習
- linux下安裝apache(httpd-2.4.3版本)各種坑
- JSP九大內置對象
- Servlet再度學習
- 開發人員系統功能設計常用辦公軟件分享
- java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener問題解決
- tomcat內存溢出解決,java.lang.OutOfMemoryError: PermGen space
- 《Java多線程編程核心技術》推薦
- 關于跳槽,是我心浮氣躁?還是我確實該離開了?
- Java I/O學習(附實例和詳解)
- Java經典設計模式之五大創建型模式(附實例和詳解)
- Java經典設計模式之七大結構型模式(附實例和詳解)
- Java經典設計模式之十一種行為型模式(附實例和詳解)
- Java內存管理
- SQL實例整理
- 數據庫面試常問的一些基本概念