You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java石头剪刀布游戏:如何用字符串调用对应策略类?

如何在Java中根据字符串实例化策略类

嘿,这个需求在策略模式的实践里太常见了!我给你两种靠谱的实现方式,你可以根据项目的复杂度和需求来选:

方法一:使用反射机制(快速实现)

如果只是快速验证需求,反射是最直接的方式——直接通过类名字符串来加载并实例化对象。假设你的策略接口叫Strategy,所有策略类(比如RockStrat、PaperStrat)都实现了这个接口,代码可以这么写:

import java.util.Scanner;

public class GameLauncher {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入策略名称(如PaperStrat):");
        String stratName = scanner.nextLine();
        
        // 注意:如果策略类在某个包下,要加上完整包名,比如 "com.yourpackage.PaperStrat"
        String fullClassName = stratName; 
        
        try {
            // 加载类并实例化
            Class<?> stratClass = Class.forName(fullClassName);
            Strategy strategy = (Strategy) stratClass.getDeclaredConstructor().newInstance();
            
            // 调用策略的方法,比如假设接口有play()方法
            strategy.play();
        } catch (ClassNotFoundException e) {
            System.out.println("找不到对应的策略类:" + stratName);
        } catch (Exception e) {
            System.out.println("实例化策略类出错:" + e.getMessage());
        }
    }
}

注意点:

  • 一定要确保输入的字符串和类名完全一致(大小写敏感),如果类在特定包下,必须加上完整的包路径;
  • 反射会抛出多种检查异常,必须做好异常处理;
  • 如果策略类没有无参构造函数,需要修改代码,调用对应的带参构造方法。

方法二:使用工厂模式(推荐,更安全可控)

反射虽然快,但存在性能开销、类型不安全、依赖类名硬编码等问题。如果是正式项目,更推荐用策略工厂来封装实例化逻辑,代码更清晰也更易维护:

首先定义策略接口:

public interface Strategy {
    void play();
}

然后实现具体策略类:

public class RockStrat implements Strategy {
    @Override
    public void play() {
        System.out.println("出石头!");
    }
}

public class PaperStrat implements Strategy {
    @Override
    public void play() {
        System.out.println("出布!");
    }
}

接下来创建策略工厂:

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class StrategyFactory {
    // 用Map存储策略名称到实例供应商的映射
    private static final Map<String, Supplier<Strategy>> STRATEGY_MAP = new HashMap<>();
    
    // 静态初始化块,注册所有策略
    static {
        STRATEGY_MAP.put("RockStrat", RockStrat::new);
        STRATEGY_MAP.put("PaperStrat", PaperStrat::new);
        // 后续加新策略,只需要在这里添加一行即可
    }
    
    // 根据名称获取策略实例
    public static Strategy getStrategy(String stratName) {
        Supplier<Strategy> supplier = STRATEGY_MAP.get(stratName);
        if (supplier == null) {
            throw new IllegalArgumentException("不存在的策略:" + stratName);
        }
        return supplier.get();
    }
}

最后在游戏中调用工厂:

import java.util.Scanner;

public class GameLauncher {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入策略名称(如PaperStrat):");
        String stratName = scanner.nextLine();
        
        try {
            Strategy strategy = StrategyFactory.getStrategy(stratName);
            strategy.play();
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}

优势:

  • 完全避免了反射的弊端,类型安全,性能更好;
  • 策略的注册和管理集中在工厂类,后续新增策略只需要修改工厂的静态块,符合开闭原则;
  • 异常处理更简洁,直接判断策略是否存在即可。

如果你的策略类很多,不想手动注册,也可以结合反射来自动扫描并加载策略类(比如扫描特定包下的所有Strategy实现类),不过这就属于进阶玩法了,基础场景下上面的工厂模式完全够用~

内容的提问来源于stack exchange,提问作者Rémy.W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:27:09