我正在尝试创建一个将所有实例移动到原点的静态方法,但我不能在实例变量(如xPosition和yPosition)上使用静态方法。
我是否必须遍历所有实例,或者是否有办法使用静态方法执行此操作?
提前致谢!
答案 0 :(得分:4)
为了确保您拥有类的所有实例,我将阻止允许通过构造构造函数private
直接创建实例并强制调用static
方法来创建和发布实例,如:
public class MyClass {
/**
* Thread-safe collection used to store all existing instances
*/
private static final Collection<MyClass> INSTANCES = new ConcurrentLinkedQueue<>();
private MyClass() {}
public static MyClass newInstance() {
// Create the instance
MyClass instance = new MyClass();
// Publish the instance
INSTANCES.add(instance);
return instance;
}
public static void release(MyClass instance) {
//Un-publish my instance
INSTANCES.remove(instance);
}
public static void releaseAll(Predicate<MyClass> predicate) {
//Un-publish all instances that match with the predicate
INSTANCES.stream().filter(predicate).forEach(INSTANCES::remove);
}
public static void apply(Consumer<MyClass> consumer) {
// Execute some code for each instance
INSTANCES.stream().forEach(consumer);
}
}
然后您的代码将是:
// Create my instance
MyClass myClass = MyClass.newInstance();
// Execute some code here
...
// Release the instance once the work is over to prevent a memory leak
MyClass.release(myClass);
...
// Execute some code on all instances
// Here it will print all instances
MyClass.apply(System.out::println);
...
// Release all instances that match with a given test
MyClass.releaseAll(myClass -> <Some Test Here>);
答案 1 :(得分:3)
如果您拥有所有实例的静态注册表,则可以使用静态方法执行此操作。
class YourClass {
static List<YourClass> instances = new ArrayList<>();
YourClass() {
instances.add(this); // Yuk! Unsafe publication.
}
static void moveAll() {
for (YourClass instance : instances) {
// Do something to instance.
}
}
}
但是我建议你不要那样做,而是要有一个非静态的注册表类:
class YourClassRegistry {
List<YourClass> instances = new ArrayList<>();
void add(YourClass instance) {
instances.add(instance);
}
void moveAll() {
for (YourClass instance : instances) {
// Do something to instance.
}
}
}
使用示例:
YourClassRegistry registry = new YourClassRegistry();
registry.add(new YourClass());
registry.add(new YourClass());
registry.add(new YourClass());
registry.moveAll();
这允许您拥有单独的“实例”组,您可以单独移动。
全局可变状态(如注册表的静态版本)是一个痛苦的问题,降低了可测试性,需要更多关注线程安全等。