【问题标题】:Getting the value from class A-setting value from class A to B-and returning the value from class B to A从A类中获取值-将A类中的值设置为B-并将B类中的值返回给A
【发布时间】:2014-03-16 21:33:29
【问题描述】:

我正在尝试学习这种获取值 - 设置值 - 从编码风格返回的值。我听说这是一种“通过价值或参考”的问题,我做了研究,但仍然坚持这个问题。不管怎样,这是我的源代码:

System.out.println(x);
int x = object2.getX(); **//I HAVE A PROBLEM HERE** 
int x2 = rand.nextInt(100);
int y = rand.nextInt(100);
int xpost = rand.nextInt(300);
int ypost = rand.nextInt(150);
allField[x] = new JTextField(String.format("        %s + %s", x2 , y));
allField[x].setBounds(xpost, ypost, 100, 30);
allField[x].setEnabled(false);
add(allField[x]);
object2.setX(x++); **//I HAVE A PROBLEM HERE TOO**

我正在尝试通过 object2.getX(); 从另一个类中获取值;从那里它将设置数组的索引。完成数组的设置后,它仍然为 0,我想增加它(x++),然后这个值为 1 的值被传递给另一个类并设置它。

这是另一个类:

public class TimerTutorial extends JFrame {
    JLabel promptLabel, timerLabel;
    int counter, x = 0;
    int changeTest;
    JTextField tf;
    JButton button;
    Timer timer;

    public int getX(){**//I HAVE A PROBLEM HERE**
        return x;
    }
    public int setX(int y){**//I HAVE A PROBLEM HERE**
        x = y;
        return this.x;
    }
}

如果你想要整个代码,但问题在此之前说明:

import java.awt.event.*;
import java.awt.*;
import java.util.Random;
import javax.swing.*;

public class TimerTutorial extends JFrame{
    JLabel promptLabel, timerLabel;
    int counter, x = 0;
    int changeTest;
    JTextField tf;
    JButton button;
    Timer timer;

    public int getX(){
        return x;
    }
    public int setX(int y){
        x = y;
        return this.x;
    }


    public TimerTutorial(){
        setLayout(new GridLayout(2,2,5,5));

        tf = new JTextField();
        add(tf);

        promptLabel = new JLabel("Enter seconds:", SwingConstants.CENTER);
        add(promptLabel);

        button = new JButton("Start Timing");
        add(button);

        timerLabel = new JLabel("Waiting...", SwingConstants.CENTER);
        add(timerLabel);

        event e = new event();
        button.addActionListener(e);
    }
    public class event implements ActionListener{
        public void actionPerformed(ActionEvent e){
            int count = (int)(Double.parseDouble(tf.getText()));
            timerLabel.setText("Time left:" +count);

            TimeClass tc = new TimeClass(count);
            timer = new Timer(1000, tc);
            timer.start();
        }
    public class TimeClass implements ActionListener{
        int counter;

        public TimeClass(int counter){
            this.counter = counter;
        }

        public void actionPerformed(ActionEvent tc){//every time timer updates this will spark
            counter--;
            JTextField[] allField = new JTextField [20];
            TimerTutorial object2 = new TimerTutorial();
            Random rand = new Random();
            System.out.println(x);
            int x = object2.getX();
            int x2 = rand.nextInt(100);int y = rand.nextInt(100);
            int xpost = rand.nextInt(300); int ypost = rand.nextInt(150);
            allField[x] = new JTextField(String.format("        %s + %s", x2 , y));
            allField[x].setBounds(xpost, ypost, 100, 30);
            allField[x].setEnabled(false);
            add(allField[x]);
            object2.setX(x++);
            if(counter>=1) {
                timerLabel.setText("Time left: "+counter);
            } else {
                timer.stop();
                timerLabel.setText("Done!");
                Toolkit.getDefaultToolkit().beep();
            }
        }
    }
    }
    public static void main(String args[]){
        TimerTutorial gui = new TimerTutorial();
        gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui.setSize(800,800);
        gui.setVisible(true);
    }
}

代码实际上运行良好。我的目标是以秒为间隔随机发布 JTextFields,其中包含随机位置和值。这里的问题是 x 不会增加。这使我的 JTextFields 成为索引 [0]。 PS:对java还是新手,任何提示将不胜感激

【问题讨论】:

  • 长代码...你能把它缩小到你面临的问题吗?在这里,我们必须为您完成。
  • 对不起!等待。我会缩小范围。 @Vak

标签: java pass-by-reference pass-by-value


【解决方案1】:

您的问题是类和类实例的混淆。此外,传递值意味着什么。您不会将值传递给类或实例,而只是传递给方法

你有actionPerformed这个方法:

TimerTutorial object2 = new TimerTutorial();
...
int x = object2.getX();
...
object2.setX(x++);

(省略与标有...的问题无关的代码) 第一个创建一个新的 (!) 对象 TimerTutorial。下一个从这个新对象中获取一些数据,但是因为它是新的并且在两者之间没有更改,所以在每次运行 actionPerformed 方法时,这将是相同的值。

最后一次setX 调用是无意义的,因为object2 将在不久之后被垃圾回收,因此设置值没有意义。顺便说一句,您设置的值与以前相同。

注意:我不解释后/前递增/递减运算符。 除非你 100% 理解它们,否则不要使用它们!!!!

从不。

曾经。

对于您还不理解的所有其他语言结构也是如此。

【讨论】:

  • 我明白了。所以每次调用它都会有一个新对象。有没有办法保留该对象中的变量? @Ingo
  • 当然,@SeanMira 有办法。问题是,实际上有很多方法,但在你的情况下,你为什么不在 TimeClass 实例中保存 TimerTutorial2 实例呢?
  • 对不起,我有点迷失了,@Ingo。对java来说还是新手。我将研究如何在对象中保存变量,我相信这个技巧会在这个程序中起作用。
  • @SeanMira 但你已经这样做了!你有很多实例变量。例如,您在 TimerTutorial 中有两个 JLabel。
【解决方案2】:

问题 1

您的第一个问题在于您对++ 运算符的使用:

object2.setX(x++);

这里发生的情况是x 的值作为参数传递给setX(),然后递增。一般来说,x++ 会增加 x,但语句的值仍然是旧的 x

int x = 0;
System.out.println(x++); // 0
System.out.println(x);   // 1

您可以改用++xx+1 来避免这种情况。

问题 2

修复 ++ 运算符的用法对您没有多大帮助,因为每次执行动作侦听器方法时都会创建一个新的 TimerTutorial 对象。

public void actionPerformed(ActionEvent tc){
    ...
    TimerTutorial object2 = new TimerTutorial(); //new object is create which initializes it's instance variable x to 0
    ...
    int x = object2.getX(); //returns the instance variable x of object2 which is 0
    ...
    object2.setX(x++); //explained in problem 1
    //After here object2 is never used again in this method
    ...
} //at the end of the method, the scope of the variable object2 ends and the object it points to will be garbage collected

我希望现在你可以看到x0,每次你执行你的动作监听器时都会被执行。如果您想保留您的对象及其在另一个范围内的状态,则必须在该范围内声明该变量。在您的情况下,动作侦听器已经是 TimerTutorial 的内部类,因此您甚至可能不需要新的 TimerTutorial 对象。你可以只使用外部类。我仍然不确定您的程序应该实现什么,但我认为这将是要走的路:

public void actionPerformed(ActionEvent tc){
    ...
    //TimerTutorial object2 = new TimerTutorial(); <= not needed
    ...
    int x = getX(); //returns the instance variable x of the outer class
    ...
    setX(x+1); //sets the instance variable x of the outer class
    ...
} //next time this method is called, the state of x will be preserved in the outer class

【讨论】:

  • 我已经改成++x了,还是一样的问题。当我再次调用 x 时,它被设置为 0。我认为问题在于 public int getX(){ return x; } public int setX(int y){ x = y;返回这个.x; }
  • @SeanMira 您是否尝试以相同的方法再次调用它,或者您是否只是第二次调用您的点击处理程序?
  • 我尝试再次调用它。还是一样。第一次打印为 0,第二次打印为 1。(由 Timer 类再次调用),仍然是 0 和 1。@AndréStannek
  • 这是因为TimerTutorial object2 = new TimerTutorial(); 在每次调用时都会创建一个新对象,然后将x 初始化为0。如果您想保留其状态,请将您的 TimerTutorial 转换为字段。
  • 投反对票的人是否愿意解释一下,以便我改进我的答案?
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多