Как я могу получить доступ к переменной из другого метода в Java? - PullRequest
0 голосов
/ 02 августа 2020

Итак, я пытаюсь получить доступ к своей переменной из задачи таймера, но, похоже, мне не удается заставить ее работать. Я читал о глобальных переменных, но не совсем понимал, как их использовать. Я новичок в Java, поэтому любое предложение было бы чрезвычайно полезным, спасибо!

public boolean verifyAnswer(String userAnswer) {
    

    
    String correctAnswer = this.questions.get(currentQuestionIndex).correctAnswerText;
    if(userAnswer.equals(correctAnswer)) {
        timer.pauseTimer();
        Timer t = new Timer();
        
        TimerTask tt = new TimerTask() {

            //This is the variable I want to use

            int score = 0;

            @Override
            public void run() {
                System.out.println(++score);
                if (score == 30) {
                    t.cancel();
                }
            };
        };
        
        t.scheduleAtFixedRate(tt, 0, 1000);
        TimerPanel timer2 = new TimerPanel();
        
        long total = 0;

        //Here is where I try to use it
        long equation = TimerTask.score / 30000;

Ответы [ 3 ]

1 голос
/ 02 августа 2020

Простейшим обходным путем было бы использование одноэлементного массива или объекта-держателя для хранения оценки, поскольку анонимные внутренние классы не могут изменять значение внешних переменных.

int[] score = {0};
TimerTask tt = new TimerTask() {

    @Override
    public void run() {
        System.out.println(++score[0]);
        if (score[0] == 30) {
            t.cancel();
        }
    };
};
//...
long equation = score[0] / 30000;
1 голос
/ 02 августа 2020

действительно может помочь глобальная переменная. Это просто переменная, объявленная вне методов, но внутри класса. Тогда это будет видно во всем классе - а также извне, если вы сделаете это public.

из вас в многопоточной среде, пожалуйста, получите доступ к нему синхронизированным способом, например, так

public class Test {

    public volatile int global_variable = 42;

    public synchronized int getGlobal_variable() {
        return global_variable;
    }

    public synchronized void setGlobal_variable(int global_variable) {
        this.global_variable = global_variable;
    }

    public void update() {
        setGlobal_variable(getGlobal_variable() + 150);

    }

    public Test() {
        try {
            while (true) {
                System.out.println(getGlobal_variable());
                update();
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public static void main(String[] args) {
        new Test();
    }
}

обратите внимание, что я добавил volatile на всякий случай. это зависит от вашего приложения, действительно ли вам это нужно.

если вас не интересует многопоточность, просто переместите объявление score за пределы вашего метода, и все будет в порядке :-)

0 голосов
/ 02 августа 2020

Причина, по которой вы не можете сделать score глобальным и изменить его, заключается в том, что локальная переменная, определенная во включающей области видимости, должна быть final или фактически final. Вы можете использовать AtomicInteger для такого случая, как показано ниже:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args) {
        Timer t = new Timer();

        // Change the type to AtomicInteger and move it out of the anonymous inner class
        final AtomicInteger score = new AtomicInteger(0);

        TimerTask tt = new TimerTask() {
            @Override
            public void run() {
                int updatedValue = score.incrementAndGet();
                System.out.println(updatedValue);
                if (updatedValue == 30) {
                    t.cancel();
                }
            };
        };

        t.scheduleAtFixedRate(tt, 0, 1000);
        // Now, you can access score here as shown below
        // long equation = score.get() / 30000;
    }
}

Вывод:

1
2
...
...
...
29
30

Поскольку мы не присваиваем никакое другое значение score, он выполняет требование final, но мы всегда можем изменить атрибут переменной final, что мы и делаем здесь.

...