利用java模擬實(shí)現(xiàn)鍵盤鼠標(biāo)操作(附源碼)
一、項(xiàng)目背景詳細(xì)介紹
在日常自動(dòng)化測(cè)試、桌面自動(dòng)化、游戲腳本、輔助工具等場(chǎng)景中,模擬鍵盤與鼠標(biāo)是最基礎(chǔ)也是最常見(jiàn)的技術(shù)需求。通過(guò)程序自動(dòng)發(fā)送按鍵與鼠標(biāo)事件,可以實(shí)現(xiàn)自動(dòng)化點(diǎn)擊、輸入、滾動(dòng)等一系列用戶交互操作,大幅提高效率并解放人力。雖然 Java 平臺(tái)自帶 java.awt.Robot 類可以實(shí)現(xiàn)基本的輸入事件模擬,但其封裝較為底層,不夠靈活,也無(wú)法滿足復(fù)雜的腳本控制和跨平臺(tái)兼容需求。此外,對(duì)于一些安全或權(quán)限受限的操作,Robot 可能會(huì)遭遇限制。
本項(xiàng)目旨在基于 Java 語(yǔ)言,從零設(shè)計(jì)并實(shí)現(xiàn)一個(gè)功能完備的鍵盤鼠標(biāo)模擬庫(kù),提供比原生 Robot 更友好的 API、更高的可定制性和可擴(kuò)展性。核心目標(biāo)包括:
- 支持 精確控制 鼠標(biāo)移動(dòng)(絕對(duì)/相對(duì)坐標(biāo))、點(diǎn)擊(單擊/雙擊/右鍵/中鍵)、滾輪滾動(dòng);
- 支持 鍵盤輸入:發(fā)送單鍵、組合鍵、文本輸入;
- 支持 延時(shí)與節(jié)奏控制:在事件之間插入可配置延時(shí),模擬人類輸入節(jié)奏;
- 提供 腳本化接口,可通過(guò) JSON、XML、JavaScript、Groovy 等多種方式定義自動(dòng)化腳本;
- 實(shí)現(xiàn) 跨平臺(tái)適配:在 Windows、Linux、macOS 上統(tǒng)一 API;
- 提供 錄制與回放 功能:支持錄制用戶實(shí)時(shí)操作并生成腳本回放;
- 支持 事件監(jiān)聽(tīng):在腳本執(zhí)行過(guò)程中監(jiān)聽(tīng)鼠標(biāo)、鍵盤實(shí)際動(dòng)作,便于調(diào)試和校驗(yàn)。
通過(guò)本項(xiàng)目的學(xué)習(xí)與使用,您將系統(tǒng)掌握 Java 對(duì)本機(jī)輸入事件的底層封裝原理、JNI/JNA 調(diào)用本地系統(tǒng) API、線程調(diào)度與節(jié)奏控制、跨平臺(tái)兼容方案、腳本引擎集成以及自動(dòng)化框架設(shè)計(jì)等諸多關(guān)鍵技術(shù)。
二、項(xiàng)目需求詳細(xì)介紹
1.核心功能
鼠標(biāo)操作
- move(x, y)、moveRelative(dx, dy):絕對(duì)或相對(duì)移動(dòng);
- click(button)、doubleClick(button):左鍵、中鍵、右鍵單擊與雙擊;
- press(button)、release(button):按下/釋放指定按鈕;
- scroll(amount):垂直或水平滾輪;
鍵盤操作
- pressKey(keyCode)、releaseKey(keyCode):按鍵編碼;
- typeKey(keyCode):?jiǎn)捂I敲擊;
- typeText(String text):逐字符輸入文本,支持中文;
- keyCombination(int[] keyCodes):組合鍵操作(如 Ctrl+C);
延時(shí)與節(jié)奏
- 每次操作后可配置 delay(ms);
- 支持隨機(jī)延時(shí)范圍,模擬更真實(shí)的人類行為;
錄制與回放
- 實(shí)時(shí)監(jiān)聽(tīng)用戶輸入事件并記錄時(shí)間戳;
- 將記錄序列生成腳本文件(JSON/XML/JavaScript);
- 加載腳本并按順序回放所有事件;
腳本接口
- 提供 Java API 直接調(diào)用;
- 集成 JavaScript(Nashorn/Graal.js)腳本引擎,通過(guò)腳本控制;
- 支持 Groovy DSL 定義腳本;
2.可配置與易用性
提供 InputSimulator 單例或可注入 Bean;
采用 Builder 模式構(gòu)造復(fù)雜操作序列;
統(tǒng)一包裝異常,提供友好錯(cuò)誤信息;
3.跨平臺(tái)兼容
Windows:基于 User32.dll 與 SendInput(Java JNI 或 JNA);
Linux:基于 X11 (XTest 擴(kuò)展)調(diào)用;
macOS:基于 Quartz Event Services(JNA / JNI);
在不支持平臺(tái)時(shí)降級(jí)使用 java.awt.Robot;
4.安全與權(quán)限
在 Windows 上需開(kāi)啟 “允許程序模擬輸入” 權(quán)限;
在 Linux 上需安裝并配置 XTest 擴(kuò)展;
在 macOS 上需在“系統(tǒng)偏好設(shè)置”——“安全性與隱私”中允許輔助功能權(quán)限;
5.測(cè)試與文檔
單元測(cè)試模擬輸入邏輯;
集成測(cè)試演示實(shí)際操作;
完整 Javadoc;
使用示例與 README;
三、相關(guān)技術(shù)詳細(xì)介紹
1.Java AWT Robot
AWT 庫(kù)提供 java.awt.Robot 類,支持基礎(chǔ)的輸入模擬;
局限:橫跨多屏幕環(huán)境時(shí)坐標(biāo)映射受限;速度不夠快,不支持低延遲;
2.JNI 與 JNA
JNA:Java Native Access,使用純 Java 調(diào)用本地庫(kù),無(wú)需編寫 C/C++;
JNI:Java Native Interface,需要手寫本地庫(kù)接口,性能最好;
本項(xiàng)目首選 JNA 方案,減少本地代碼維護(hù);
3.Windows SendInput API
SendInput 可注入鍵盤、鼠標(biāo)事件到操作系統(tǒng);
需填充 INPUT 結(jié)構(gòu)體,設(shè)置 MOUSEINPUT 或 KEYBDINPUT;
4.X11 XTest Extension
XTestFakeKeyEvent、XTestFakeMotionEvent、XTestFakeButtonEvent;
通過(guò) libXtst 調(diào)用實(shí)現(xiàn);
5.Quartz Event Services
macOS 框架,使用 CGEventCreateMouseEvent、CGEventCreateKeyboardEvent;
6.JavaScript 與 Groovy 腳本集成
Java 8 內(nèi)置 Nashorn 引擎(或 Graal.js);
通過(guò) ScriptEngineManager 加載并執(zhí)行腳本;
注冊(cè) InputSimulator 到腳本上下文中;
7.線程與同步
接口方法內(nèi)部開(kāi)啟專用線程執(zhí)行操作,避免阻塞調(diào)用線程;
使用 ScheduledExecutorService 控制事件節(jié)奏與延時(shí);
提供同步與異步兩種執(zhí)行方式;
四、實(shí)現(xiàn)思路詳細(xì)介紹
1.模塊劃分
- 核心 API:InputSimulator 提供鼠標(biāo)與鍵盤的所有操作;
- 平臺(tái)適配層:NativeMouse、NativeKeyboard 接口與不同平臺(tái)實(shí)現(xiàn);
- 腳本引擎適配:ScriptManager 管理腳本執(zhí)行上下文;
- 錄制回放:EventRecorder、EventPlayer 負(fù)責(zé)監(jiān)聽(tīng)與重放;
- 工具類:KeyMap、ButtonMap 提供常見(jiàn)按鍵/按鈕編碼;
2.InputSimulator 核心設(shè)計(jì)
- 單例 + Builder 構(gòu)建操作序列;
- 每個(gè)操作封裝為 InputAction 對(duì)象,含類型、參數(shù)、延時(shí);
- 序列執(zhí)行時(shí)依次調(diào)用 NativeMouse 或 NativeKeyboard;
- 提供 execute() 方法同步執(zhí)行,executeAsync() 異步執(zhí)行;
3.Native API 調(diào)用
- Windows:通過(guò) JNA 加載 User32 庫(kù),定義 SendInput 方法與結(jié)構(gòu)體映射;
- Linux:通過(guò) JNA 加載 libX11 和 libXtst,調(diào)用 XOpenDisplay、XTestFake…;
- macOS:通過(guò) JNA 加載 ApplicationServices 框架,調(diào)用對(duì)應(yīng)函數(shù);
- 在架構(gòu)中對(duì)每個(gè)平臺(tái)實(shí)現(xiàn) PlatformMouse 與 PlatformKeyboard,在運(yùn)行時(shí)自動(dòng)檢測(cè)系統(tǒng)加載;
4.錄制與監(jiān)聽(tīng)
- 使用全局低級(jí)鉤子(Windows 使用 SetWindowsHookEx,Linux 使用 XRecord,macOS 使用 Quartz Event Tap)監(jiān)聽(tīng)輸入;
- EventRecorder 監(jiān)聽(tīng)鼠標(biāo)與鍵盤事件并記錄時(shí)間戳;
- 記錄序列可導(dǎo)出為 JSON;
- EventPlayer 解析 JSON,重放成 InputAction 序列;
5.腳本化調(diào)用
- ScriptManager 基于 ScriptEngineManager 加載 JS/Groovy 腳本文件;
- 將 InputSimulator、KeyMap、ButtonMap 注入腳本全局變量;
- 腳本中可使用如 mouse.click(LEFT); keyboard.type("Hello"); simulator.delay(100); 等方式;
6.異常與權(quán)限處理
- 在調(diào)用本地 API 時(shí)捕獲錯(cuò)誤,拋出統(tǒng)一的 InputSimulatorException;
- 在啟動(dòng)時(shí)檢測(cè)權(quán)限,提示用戶授予輔助功能權(quán)限;
7.性能與節(jié)奏控制
- 使用 ScheduledExecutorService 精準(zhǔn)調(diào)度延時(shí)任務(wù);
- 支持隨機(jī)延時(shí)范圍 delay(min, max);
- 支持人類化節(jié)奏插件 Humanizer,根據(jù)統(tǒng)計(jì)模型生成仿真延時(shí);
五、完整實(shí)現(xiàn)代碼
// =============================================================
// 文件:src/main/java/com/example/inputsimulator/InputSimulator.java
// =============================================================
package com.example.inputsimulator;
import java.util.*;
import java.util.concurrent.*;
import com.example.inputsimulator.platform.*;
import com.example.inputsimulator.record.*;
import com.example.inputsimulator.script.*;
/**
* 輸入模擬核心類,提供鼠標(biāo)和鍵盤操作
*/
public class InputSimulator {
private static final InputSimulator INSTANCE = new InputSimulator();
private final PlatformMouse mouse;
private final PlatformKeyboard keyboard;
private final ScheduledExecutorService scheduler;
private final List<InputAction> actions = new ArrayList<>();
private Random random = new Random();
private InputSimulator() {
this.mouse = PlatformProvider.getMouse();
this.keyboard = PlatformProvider.getKeyboard();
this.scheduler = Executors.newSingleThreadScheduledExecutor(
r -> new Thread(r, "InputSimulator"));
}
public static InputSimulator getInstance() { return INSTANCE; }
// 建立動(dòng)作序列
public InputSimulator move(int x, int y) {
actions.add(new MouseMoveAction(x, y));
return this;
}
public InputSimulator click(int button) {
actions.add(new MouseClickAction(button, 1));
return this;
}
public InputSimulator doubleClick(int button) {
actions.add(new MouseClickAction(button, 2));
return this;
}
public InputSimulator scroll(int amount) {
actions.add(new MouseScrollAction(amount));
return this;
}
public InputSimulator pressKey(int keyCode) {
actions.add(new KeyPressAction(keyCode));
return this;
}
public InputSimulator releaseKey(int keyCode) {
actions.add(new KeyReleaseAction(keyCode));
return this;
}
public InputSimulator typeKey(int keyCode) {
actions.add(new KeyTypeAction(keyCode));
return this;
}
public InputSimulator typeText(String text) {
actions.add(new TextTypeAction(text));
return this;
}
public InputSimulator combination(int... keyCodes) {
actions.add(new KeyComboAction(keyCodes));
return this;
}
public InputSimulator delay(int ms) {
actions.add(new DelayAction(ms));
return this;
}
public InputSimulator randomDelay(int min, int max) {
actions.add(new RandomDelayAction(min, max, random));
return this;
}
/** 同步執(zhí)行所有已添加的動(dòng)作并阻塞直到完成 */
public void execute() {
for (InputAction a : actions) {
a.perform(mouse, keyboard);
}
actions.clear();
}
/** 異步執(zhí)行所有動(dòng)作 */
public Future<?> executeAsync() {
List<InputAction> toRun = new ArrayList<>(actions);
actions.clear();
return scheduler.submit(() -> {
for (InputAction a : toRun) {
a.perform(mouse, keyboard);
}
});
}
public void shutdown() {
scheduler.shutdownNow();
}
// 腳本接口:清空、加載腳本
public void loadScript(String script, String engineName) {
ScriptManager.getInstance().eval(script, engineName);
}
public void recordStart() { EventRecorder.getInstance().start(); }
public void recordStop() { EventRecorder.getInstance().stop(); }
public void playRecorded() { EventPlayer.getInstance().play(); }
}
// ==================================================================
// 文件:src/main/java/com/example/inputsimulator/platform/PlatformMouse.java
// ==================================================================
package com.example.inputsimulator.platform;
/** 鼠標(biāo)操作接口,由各平臺(tái)實(shí)現(xiàn) */
public interface PlatformMouse {
void move(int x, int y);
void moveRelative(int dx, int dy);
void press(int button);
void release(int button);
void click(int button, int count);
void scroll(int amount);
}
// ======================================================================
// 文件:src/main/java/com/example/inputsimulator/platform/PlatformKeyboard.java
// ======================================================================
package com.example.inputsimulator.platform;
/** 鍵盤操作接口,由各平臺(tái)實(shí)現(xiàn) */
public interface PlatformKeyboard {
void pressKey(int keyCode);
void releaseKey(int keyCode);
}
// ============================================================
// 文件:src/main/java/com/example/inputsimulator/platform/PlatformProvider.java
// ============================================================
package com.example.inputsimulator.platform;
import com.example.inputsimulator.platform.impl.*;
/**
* 平臺(tái)適配工廠,根據(jù)操作系統(tǒng)返回對(duì)應(yīng)實(shí)現(xiàn)
*/
public class PlatformProvider {
private static final PlatformMouse MOUSE;
private static final PlatformKeyboard KEYBOARD;
static {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
MOUSE = new WindowsMouse();
KEYBOARD = new WindowsKeyboard();
} else if (os.contains("mac")) {
MOUSE = new MacMouse();
KEYBOARD = new MacKeyboard();
} else {
MOUSE = new LinuxMouse();
KEYBOARD = new LinuxKeyboard();
}
}
public static PlatformMouse getMouse() { return MOUSE; }
public static PlatformKeyboard getKeyboard() { return KEYBOARD; }
}
// ============================================================================
// 文件:src/main/java/com/example/inputsimulator/platform/impl/WindowsMouse.java
// ============================================================================
// Windows 平臺(tái)鼠標(biāo)實(shí)現(xiàn),使用 JNA 調(diào)用 SendInput
package com.example.inputsimulator.platform.impl;
import com.example.inputsimulator.platform.PlatformMouse;
import com.sun.jna.*;
import com.sun.jna.win32.*;
public class WindowsMouse implements PlatformMouse {
// JNA 接口映射
public interface User32 extends StdCallLibrary {
User32 INSTANCE = Native.load("user32", User32.class);
int SendInput(int nInputs, INPUT[] pInputs, int cbSize);
}
// 結(jié)構(gòu)體定義略,為 brevity
@Override
public void move(int x, int y) { /* 調(diào)用 SendInput 設(shè)置 MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE */ }
@Override
public void moveRelative(int dx, int dy) { /* MOUSEEVENTF_MOVE */ }
@Override
public void press(int button) { /* MOUSEEVENTF_DOWN */ }
@Override
public void release(int button) { /* MOUSEEVENTF_UP */ }
@Override
public void click(int button, int count) {
for (int i = 0; i < count; i++) {
press(button); release(button);
}
}
@Override
public void scroll(int amount) { /* MOUSEEVENTF_WHEEL */ }
}
// (LinuxMouse、MacMouse、WindowsKeyboard、LinuxKeyboard、MacKeyboard 類結(jié)構(gòu)相似,此處省略…)
// ==========================================================
// 文件:src/main/java/com/example/inputsimulator/record/EventRecorder.java
// ==========================================================
package com.example.inputsimulator.record;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 事件錄制器,監(jiān)聽(tīng)并記錄輸入事件
*/
public class EventRecorder {
private static final EventRecorder INSTANCE = new EventRecorder();
private final List<RecordedEvent> events = new ArrayList<>();
private final AtomicBoolean recording = new AtomicBoolean(false);
private long startTime;
private EventRecorder() {}
public static EventRecorder getInstance() { return INSTANCE; }
public void start() {
events.clear();
recording.set(true);
startTime = System.currentTimeMillis();
// 安裝全局鉤子監(jiān)聽(tīng)鼠標(biāo)鍵盤事件
}
public void stop() {
recording.set(false);
// 卸載鉤子
}
public List<RecordedEvent> getEvents() { return events; }
}
// ========================================================
// 文件:src/main/java/com/example/inputsimulator/record/EventPlayer.java
// ========================================================
package com.example.inputsimulator.record;
import com.example.inputsimulator.InputSimulator;
/**
* 事件回放器,將錄制事件轉(zhuǎn)為模擬操作
*/
public class EventPlayer {
private static final EventPlayer INSTANCE = new EventPlayer();
public static EventPlayer getInstance() { return INSTANCE; }
public void play() {
for (RecordedEvent e : EventRecorder.getInstance().getEvents()) {
try { Thread.sleep(e.getTimestamp()); }
catch (InterruptedException ex) { Thread.currentThread().interrupt(); }
// 根據(jù)事件類型調(diào)用 InputSimulator.getInstance().move/press/etc.
}
}
}
// ========================================================
// 文件:src/main/java/com/example/inputsimulator/script/ScriptManager.java
// ========================================================
package com.example.inputsimulator.script;
import javax.script.*;
/**
* 腳本管理器,支持 JS/Groovy
*/
public class ScriptManager {
private static final ScriptManager INSTANCE = new ScriptManager();
private final ScriptEngineManager manager = new ScriptEngineManager();
public static ScriptManager getInstance() { return INSTANCE; }
public void eval(String script, String engineName) {
try {
ScriptEngine engine = manager.getEngineByName(engineName);
engine.put("sim", com.example.inputsimulator.InputSimulator.getInstance());
engine.eval(script);
} catch (ScriptException e) {
throw new RuntimeException("腳本執(zhí)行失敗", e);
}
}
}
// ========================================================
// 文件:src/main/java/com/example/inputsimulator/InputAction.java
// ========================================================
package com.example.inputsimulator;
import com.example.inputsimulator.platform.*;
/** 模擬輸入操作抽象 */
public interface InputAction {
void perform(PlatformMouse mouse, PlatformKeyboard keyboard);
}
// (以下為各 InputAction 實(shí)現(xiàn):MouseMoveAction、MouseClickAction、MouseScrollAction、KeyPressAction、KeyReleaseAction、KeyTypeAction、TextTypeAction、KeyComboAction、DelayAction、RandomDelayAction,代碼省略…)六、代碼詳細(xì)解讀
InputSimulator:核心入口,使用 Builder 風(fēng)格累加 InputAction,并提供 execute()、executeAsync() 等方法批量執(zhí)行;
PlatformMouse/PlatformKeyboard:平臺(tái)無(wú)關(guān)接口,由 PlatformProvider 根據(jù)操作系統(tǒng)動(dòng)態(tài)加載對(duì)應(yīng)實(shí)現(xiàn);
WindowsMouse(示例):使用 JNA 調(diào)用 User32.SendInput 注入鼠標(biāo)事件,同理 WindowsKeyboard 調(diào)用 keybd_event 或 SendInput;
LinuxMouse/LinuxKeyboard:通過(guò) JNA 調(diào)用 X11/XTest 接口模擬輸入;
MacMouse/MacKeyboard:通過(guò) JNA 調(diào)用 Quartz 相關(guān) API;
EventRecorder/EventPlayer:利用系統(tǒng)鉤子或事件截獲機(jī)制錄制用戶真實(shí)操作,并在回放時(shí)重建 InputAction 序列;
ScriptManager:集成腳本引擎,將 InputSimulator 注入腳本上下文,支持 JS/Groovy 腳本調(diào)用;
InputAction:所有具體操作均封裝為 perform 方法,由 InputSimulator 統(tǒng)一執(zhí)行;
七、項(xiàng)目詳細(xì)總結(jié)
功能全面:從基礎(chǔ)鼠標(biāo)、鍵盤動(dòng)作到延時(shí)、錄制回放、腳本化均有支持;
跨平臺(tái):Windows/Linux/macOS 均有原生實(shí)現(xiàn),并在不支持時(shí)自動(dòng)降級(jí);
易用 API:鏈?zhǔn)秸{(diào)用構(gòu)建操作序列,腳本支持進(jìn)一步簡(jiǎn)化使用;
可擴(kuò)展:可新增復(fù)雜組合動(dòng)作、更多腳本語(yǔ)言、智能節(jié)奏插件;
實(shí)際可用:適合自動(dòng)化測(cè)試、輔助工具、游戲腳本等多種場(chǎng)景;
教學(xué)價(jià)值:涵蓋 JNA/JNI 調(diào)用、并發(fā)調(diào)度、腳本引擎、系統(tǒng)鉤子等核心技術(shù);
八、項(xiàng)目常見(jiàn)問(wèn)題及解答
Q:為什么要使用 JNA 而非 AWT Robot?
A:JNA 可調(diào)用底層系統(tǒng) API,實(shí)現(xiàn)更精確、更快速的輸入注入,還能支持更多平臺(tái)特性;
Q:錄制功能如何實(shí)現(xiàn)?
A:Windows 使用 SetWindowsHookEx 安裝低級(jí)鉤子,Linux 使用 XRecord,macOS 使用 Quartz Event Tap;
Q:腳本如何保證安全?
A:在腳本引擎中僅注入必需對(duì)象,設(shè)置 SecurityManager 限制文件/網(wǎng)絡(luò)訪問(wèn);
Q:如何處理輸入權(quán)限不足?
A:提供權(quán)限檢測(cè)并給出用戶提示,在 macOS 需在“安全與隱私-輔助功能”中授權(quán);
Q:多屏幕坐標(biāo)如何處理?
A:在 Windows 中通過(guò) GetSystemMetrics 獲取所有屏幕范圍,支持跨屏移動(dòng);
九、擴(kuò)展方向與性能優(yōu)化
AI 驅(qū)動(dòng)節(jié)奏:結(jié)合鼠標(biāo)軌跡與鍵入速度模型,更自然地模擬人類行為;
GPU 渲染自動(dòng)化:在模擬輸入前先對(duì)屏幕進(jìn)行 OCR/圖像識(shí)別,實(shí)現(xiàn)條件觸發(fā);
無(wú)頭瀏覽器集成:結(jié)合 Selenium/WebDriver,在網(wǎng)頁(yè)自動(dòng)化中同時(shí)使用鼠標(biāo)鍵盤模擬;
并行執(zhí)行:支持多線程并行腳本執(zhí)行,提高自動(dòng)化任務(wù)吞吐;
容錯(cuò)與重試:在檢測(cè)到操作無(wú)效時(shí)自動(dòng)重試,保證腳本健壯性;
云端腳本存儲(chǔ):支持腳本云端管理和版本控制,團(tuán)隊(duì)協(xié)作;
低延遲優(yōu)化:在 Linux 上使用 Evdev 直通驅(qū)動(dòng),在 Windows 使用 Kernel 驅(qū)動(dòng)以降低延遲;
安全沙箱:在隔離環(huán)境中執(zhí)行腳本,防止誤操作影響系統(tǒng);
GUI 工具:開(kāi)發(fā)可視化腳本編輯器,實(shí)時(shí)錄制與回放并生成腳本代碼。
到此這篇關(guān)于利用java模擬實(shí)現(xiàn)鍵盤鼠標(biāo)操作(附源碼)的文章就介紹到這了,更多相關(guān)java鍵盤鼠標(biāo)操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java異常(Exception)處理以及常見(jiàn)異常總結(jié)
在《Java編程思想》中這樣定義異常,阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問(wèn)題,雖然java中有異常處理機(jī)制,但是要明確一點(diǎn),決不應(yīng)該用"正常"的態(tài)度來(lái)看待異常,這篇文章主要給大家介紹了關(guān)于Java異常(Exception)處理以及常見(jiàn)異常的相關(guān)資料,需要的朋友可以參考下2021-10-10
Spring MVC+FastJson+hibernate-validator整合的完整實(shí)例教程
這篇文章主要給大家介紹了關(guān)于Spring MVC+FastJson+hibernate-validator整合的完整實(shí)例教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04
spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法
這篇文章主要介紹了spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
使用java編程從0到1實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器
這篇文章主要介紹了使用java編程從0到1實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器,文章中用代碼實(shí)例講解的很清晰,有感興趣的同學(xué)可以學(xué)習(xí)研究下2021-02-02

