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

Java类与方法问题:非静态调用错误及变量重置求助

解决你的票务程序两个核心问题

嘿,我来帮你拆解并解决这两个问题——都是Java新手常踩的基础概念坑,咱们一步步来:


问题1:非静态方法无法从静态上下文引用

原因分析

这个错误的核心是静态成员和实例成员的访问规则搞混了:

  • writeOutput() 被声明为 static,静态方法属于类本身,不需要创建实例就能调用,但它只能访问静态变量/静态方法;
  • 而 getadultSum() 是实例方法,option、adultSum 这类变量如果没加static,属于类的具体实例,必须通过对象才能访问。静态方法里直接调用实例方法/变量,自然会报错。

解决方案

调整TheMachine类的结构,把需要保留状态的变量改成实例成员,同时把writeOutput()改成实例方法(去掉static):

public class TheMachine {
    // 声明为实例成员,保存当前机器的状态
    private int option;
    private int adultSum = 0; // 初始化默认值

    // 去掉static,改成实例方法
    public void writeOutput() {
        System.out.println(" ------------------------------------------\n");
        System.out.println("Adults: " + getadultSum());
    }

    public int getadultSum() {
        switch (option) {
            case 3:
                adultSum += 1;
                break;
            case 4:
                adultSum -= 1;
                break;
            // 必须加default,避免无返回值的编译错误
            default:
                break;
        }
        return adultSum;
    }

    // 给option加setter方法,用于外部设置选项
    public void setOption(int option) {
        this.option = option;
    }
}

然后在调用时,通过你创建的machineOne实例来调用方法:

public static void machineOne(int counter) {
    Scanner keyboard = new Scanner(System.in);
    int choice = keyboard.nextInt(); // 先读取用户输入的选项
    TheMachine machineOne = new TheMachine();
    
    machineOne.setOption(choice); // 设置当前选项
    machineOne.writeOutput(); // 调用实例方法输出
}

问题2:变量每次输入都会重置为0

原因分析

你在writeOutput()方法里定义的childTickets、adultSum等变量是局部变量:

static void writeOutput() {
    int childTickets = 0;
    int adultTickets = 0;
    // ...其他变量
}

局部变量的生命周期只在方法执行期间,每次调用方法时都会重新初始化值为0,方法执行完就销毁,自然没法保留之前的输入状态。

解决方案

把需要持久化状态的变量移到类的成员位置(方法外面),作为实例变量(每个机器实例独立保存自己的票务数据,更符合你的业务场景):

public class TheMachine {
    // 声明为实例成员,初始化默认值
    private int childTickets = 0;
    private int adultTickets = 0;
    private String route = "";
    private int childSum = 0;
    private int adultSum = 0;
    private int creditSum = 0;
    private int choice; // 保存用户的选择

    public void setChoice(int choice) {
        this.choice = choice;
    }

    public void updateAndWriteOutput() {
        // 根据choice更新状态
        switch (choice) {
            case 1:
                route = "Uptown";
                break;
            case 2:
                route = "Downtown";
                break;
            case 3:
                adultSum += 1;
                break;
            default:
                break;
        }
        // 输出当前状态
        System.out.println("当前路线: " + route);
        System.out.println("成人票累计: " + adultSum);
        // ...其他需要输出的内容
    }
}

这样每次调用updateAndWriteOutput()时,变量会基于之前的状态更新,不会重置为0。


最后补两个小建议:

  1. 不要在每个方法里都创建新的Scanner实例,建议在main里创建一个全局Scanner,传递给其他方法使用,避免资源浪费;
  2. 处理用户输入时加上异常捕获(比如用户输入非数字的情况),避免程序直接崩溃。

内容的提问来源于stack exchange,提问作者Twissted

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:36:52