【问题标题】:Eclipse debug mode changing variablesEclipse 调试模式更改变量
【发布时间】:2015-01-07 00:07:49
【问题描述】:

在使用 Eclipse IDE 进行 Java 编程时,我有时会使用调试功能。很多时候,我喜欢在程序运行时实时更改变量。但是,我经常发现更改一些变量实际上不会影响当前正在运行的程序。

我的问题是:是否有一定的调试规则?哪些变量在调试器的范围内?

如果这是一个愚蠢的问题,我很抱歉。我对在 Eclipse 中进行调试和一般编程相当陌生。

下面的代码是一个示例。很抱歉,如果很难阅读或其他问题,但问题是:在 Ball 类中,每当我更改最终变量(例如 PARTICLES_PER_CLICKSPEED)时,它们都会实时更新,我可以看到差异程序窗口,但是当我更改 RADIUS 变量时,它什么也不做,即使它与其他两个变量在同一个类中。

public class Main {

    public static final int WIDTH = 1280;
    public static final int HEIGHT = 720;
    public static Ball[] ball = new Ball[100000];
    public Main() {
        try {
            Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
            Display.create();
            Display.setTitle("Game Engine");

        } catch (LWJGLException e) {

            e.printStackTrace();
        }

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
        glMatrixMode(GL_MODELVIEW);


        boolean[] doOnce = new boolean[10];
        boolean gravity = false;
        while (!Display.isCloseRequested()) {

            if (Mouse.isButtonDown(1) || Mouse.isButtonDown(1)) {
                if (!doOnce[0]) {
                    Ball.createParticles();
                    doOnce[0]=true;
                }

            } else {
                doOnce[0] = false;
            }

            glClear(GL_COLOR_BUFFER_BIT);

            for (int i = 1; i <= Ball.ballAmount; i++) {
                ball[i].updatePosition(gravity);
                if (Mouse.isButtonDown(0)) {
                    gravity = true;
                } else {
                    gravity = false;
                }

                if (ball[i].position.x > 0 && ball[i].position.y > 0 && ball[i].position.x < WIDTH && ball[i].position.y < HEIGHT) {
                    glBegin(GL_TRIANGLE_FAN);
                    glVertex2d(ball[i].position.x, ball[i].position.y);
                    for(int u=0;u<=360;u+=5){
                        glVertex2d(ball[i].position.x+Math.cos(u)*Ball.RADIUS, ball[i].position.y+Math.sin(u)*Ball.RADIUS);
                    }
                    glEnd();
                }

            }
            System.out.println("Particle Amount: " + Ball.ballAmount);

            Display.update();
            Display.sync(60);
        }
        Display.destroy();
        System.exit(0);
    }

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

class Ball {

    public Vector2f position, velocity;
    public static final int RADIUS = 10;
    public static final int INITIAL_SPEED = 5;
    public static final int SPEED = 2;
    public static final int PARTICLES_PER_CLICK = 50;

    public static int ballAmount = 0;

    public double r, g, b;

    public static Random rnd = new Random();

    public Ball(double x, double y) {
        int angle = rnd.nextInt(360);
        position = new Vector2f((float) x, (float) y);
        velocity = new Vector2f((float) Math.cos(angle) * rnd.nextFloat() * INITIAL_SPEED, (float) Math.sin(angle) * rnd.nextFloat() * INITIAL_SPEED);

        this.r = rnd.nextDouble();
        this.g = rnd.nextDouble();
        this.b = rnd.nextDouble();
    }

    public void updatePosition(boolean gravity) {
        this.position.x += this.velocity.x * SPEED;
        this.position.y += this.velocity.y * SPEED;
        if (gravity) {
            double dx = this.position.x - Mouse.getX();
            double dy = this.position.y - (Main.HEIGHT - Mouse.getY());
            double distance = Math.sqrt(dx * dx + dy * dy);

            this.velocity.x -= (this.position.x - Mouse.getX()) / distance;
            this.velocity.y -= (this.position.y - (Main.HEIGHT - Mouse.getY())) / distance;
        } else {
            this.velocity.x *= 0.99;
            this.velocity.y *= 0.99;
        }

    }

    public static void createParticles() {
        for (int i = 1; i <= PARTICLES_PER_CLICK; i++) {

            ballAmount += 1;
            Main.ball[ballAmount] = new Ball(Mouse.getX(),Main.HEIGHT- Mouse.getY());
        }
    }

}

【问题讨论】:

  • 我想在时间紧迫的情况下更详细地解决这个问题,但总的来说,您希望避免在调试时修改变量,并让值有机地出现。只有在特殊情况下,通过调试器注入一个值才是一个好主意。

标签: java eclipse debugging variables


【解决方案1】:

如果优化器看到一个最终变量,它就知道它的值不会改变。它用这些知识做什么取决于它。它可能什么都不做(就像在您使用 PARTICLES_PER_CLICK 或 SPEED 的情况下似乎发生的那样),或者它可能只是用实际值替换所有出现的该变量。没有特殊规则,除了不要改变最终变量的值

【讨论】:

    【解决方案2】:

    没有特殊规定,除了不改变final变量的值。

    实际上,Eclipse 4.23(2022 年第二季度,七年后)现在更清晰了:

    Warning about changing final fields

    自 Eclipse 3.1 起,Eclipse Java 调试器允许更改最终字段值。

    虽然技术上可行,但此类更改的后果并非微不足道,可能会影响看似不相关的代码并导致各种危险后果。

    因此,Eclipse 4.23 Java 调试器现在显示一个新警告:

    此警告默认启用,可通过首选项禁用:

    此外,“org.eclipse.debug.ui.variableValueEditors”扩展点已更新,允许自定义产品将自己的“variableValueEditor”实现贡献给现有的调试模型,并对final 字段修改拥有更多控制权。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-23
      相关资源
      最近更新 更多