如何一次更改类的所有实例的实例变量,Java

问题描述 投票:0回答:1

我想拥有一个类的多个实例,但是能够一次更改一个变量的所有非静态实例。也许这段代码会更清晰:

public class Example {
     public int _x; //_x and _y are NOT static
     public int _y;
     Example (int x, int y) {
     _x = x;
     _y = y;
     }
     public void zeroThem() {
     _x = 0;
     _y = 0;
     }
}

zeroThem()方法的重点是我可能有

Example A = new Example(1, 2);
Example B = new Example(3, 4);

但是一旦我拨打类似的电话:A.zeroThem();以下是正确的:

A._x == 0;
B._x == 0;
A._y == 0;
B._y == 0;

有没有办法使_x和_y保持静态?

java class static instance non-static
1个回答
-1
投票

这可以通过以下修复程序来实现:

  1. 您的实例变量必须为volatile
  2. 您需要具有Example实例的静态synchronized静态集合并对其进行迭代。
  3. 根据您的请求,您需要使方法zeroAll调用实例方法zeroThemzeroAll可以实现为非静态的,但是一旦它影响Exampleall实例,最好将其标记为static
public class Example {

    private static List<Example> all = Collections.synchronizedList(
        new ArrayList<>());

    public volatile int _x; //_x and _y are NOT static
    public volatile int _y;

    Example (int x, int y) {
        this._x = x;
        this._y = y;
        Example.all.add(this);
    }

    public void zeroThem() {
        _x = 0;
        _y = 0;
    }

    public static void zeroAll() {
        synchronized(Example.all) {
            Example.all.forEach(Example::zeroThem);
        }
    }
}

更新使用WeakReferenceReferenceQueue解决注释以解决内存泄漏问题:

import java.lang.ref.*;
import java.util.*;

public class Example {

    private static final ReferenceQueue<Example> refQueue = new ReferenceQueue<>();
    private static final List<WeakReference<Example>> all = Collections.synchronizedList(new ArrayList<>());

    public volatile int _x; //_x and _y are NOT static
    public volatile int _y;

    Example (int x, int y) {
        this._x = x;
        this._y = y;
        Example.all.add(new WeakReference<>(this, refQueue));
    }

    public void zeroThem() {
        _x = 0;
        _y = 0;
    }

    public static void zeroAll() {
        synchronized(Example.all) {
            Example.all.removeIf(ref -> ref.get() == null); // delete non-existing instances
            Example.all
                .stream()
                .map(WeakReference::get)
                .forEach(Example::zeroThem);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.