当前位置:首页 > Java

java如何撤销

2026-03-20 06:07:45Java

撤销操作的基本方法

在Java中实现撤销功能通常依赖于设计模式中的命令模式(Command Pattern)。核心思想是将操作封装为对象,记录操作的历史记录,便于回退。

定义一个抽象命令接口:

public interface Command {
    void execute();
    void undo();
}

具体命令实现需保存操作前的状态:

public class ConcreteCommand implements Command {
    private Receiver receiver;
    private Object previousState;

    public void execute() {
        previousState = receiver.getState(); // 保存状态
        receiver.action();
    }

    public void undo() {
        receiver.setState(previousState); // 恢复状态
    }
}

历史记录管理

使用栈结构存储命令历史:

java如何撤销

public class CommandHistory {
    private Stack<Command> history = new Stack<>();

    public void push(Command c) {
        history.push(c);
    }

    public Command pop() {
        return history.pop();
    }

    public boolean isEmpty() {
        return history.isEmpty();
    }
}

调用示例:

CommandHistory history = new CommandHistory();
Command cmd = new ConcreteCommand(receiver);

cmd.execute();   // 执行操作
history.push(cmd); // 记录

// 撤销操作
if (!history.isEmpty()) {
    history.pop().undo();
}

多级撤销实现

扩展历史记录管理支持多步撤销:

java如何撤销

public class MultiLevelHistory {
    private Stack<Command> undoStack = new Stack<>();
    private Stack<Command> redoStack = new Stack<>();

    public void execute(Command cmd) {
        cmd.execute();
        undoStack.push(cmd);
        redoStack.clear(); // 新操作后清空重做栈
    }

    public void undo() {
        if (!undoStack.isEmpty()) {
            Command cmd = undoStack.pop();
            cmd.undo();
            redoStack.push(cmd);
        }
    }

    public void redo() {
        if (!redoStack.isEmpty()) {
            Command cmd = redoStack.pop();
            cmd.execute();
            undoStack.push(cmd);
        }
    }
}

状态快照方案

对于复杂对象,可采用备忘录模式(Memento Pattern)保存完整状态:

public class Originator {
    private String state;

    public Memento save() {
        return new Memento(state);
    }

    public void restore(Memento m) {
        state = m.getState();
    }

    // Memento为内部类
    public static class Memento {
        private final String state;
        private Memento(String state) {
            this.state = state;
        }
        private String getState() {
            return state;
        }
    }
}

使用示例:

Originator originator = new Originator();
Stack<Originator.Memento> history = new Stack<>();

// 保存状态
history.push(originator.save());

// 恢复状态
originator.restore(history.pop());

事务性撤销

对于数据库操作等场景,需结合事务管理:

try {
    Connection conn = DriverManager.getConnection(DB_URL);
    conn.setAutoCommit(false); // 关闭自动提交

    // 执行SQL操作
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("INSERT INTO table VALUES (...)");

    // 用户触发撤销
    conn.rollback(); // 回滚事务
} catch (SQLException e) {
    e.printStackTrace();
}

标签: java
分享给朋友:

相关文章

java如何

java如何

Java 基础语法 Java 是一种面向对象的编程语言,语法相对严谨。每个 Java 程序必须包含一个 main 方法作为程序入口。以下是一个简单的 Java 程序示例: public class…

java如何react

java如何react

在Java中使用React 要在Java项目中集成React,通常需要将React前端与Java后端结合使用。以下是几种常见的方法: 使用Spring Boot作为后端 Spring Boot是一个…

如何配置java环境

如何配置java环境

下载JDK安装包 访问Oracle官网或OpenJDK官网,选择适合操作系统的JDK版本(如Windows、macOS或Linux)。下载完成后,运行安装程序并按照提示完成安装。 设置环境变量 右键…

如何搭建java开发环境

如何搭建java开发环境

下载并安装JDK 从Oracle官网或OpenJDK下载适合操作系统的JDK版本。运行安装程序并按照提示完成安装,建议选择默认路径以减少配置复杂度。 配置环境变量 在系统环境变量中添加JAVA_HO…

java如何避免死锁

java如何避免死锁

避免死锁的方法 固定顺序获取锁 确保所有线程按照相同的顺序获取多个锁。例如,若需要获取锁A和锁B,所有线程必须先获取A再获取B,避免交叉依赖导致的死锁。这种方式破坏了“循环等待”条件。 使用锁超时机…

java版本如何查看

java版本如何查看

查看Java版本的命令行方法 在命令行或终端中运行以下命令可以查看当前安装的Java版本: java -version 输出示例: java version "1.8.0_301" Java(TM…