如何让Java中的所有实例都做一些事情
我试图创建一个将所有实例移动到原点的静态方法,但不能对实例变量(如xPosition和yPosition)使用静态方法 我是否必须遍历所有实例,或者是否有一种方法可以使用静态方法来实现这一点如何让Java中的所有实例都做一些事情,java,static-methods,Java,Static Methods,我试图创建一个将所有实例移动到原点的静态方法,但不能对实例变量(如xPosition和yPosition)使用静态方法 我是否必须遍历所有实例,或者是否有一种方法可以使用静态方法来实现这一点 提前谢谢 如果您拥有所有实例的静态注册表,则可以使用静态方法来完成 class YourClass { static List<YourClass> instances = new ArrayList<>(); YourClass() { instances.add
提前谢谢 如果您拥有所有实例的静态注册表,则可以使用静态方法来完成
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.
}
}
}
这允许您拥有单独的“实例”组,您可以单独移动它们
全局可变状态(如注册表的静态版本)是一个棘手的问题,降低了可测试性,需要在线程安全等方面更加小心。为了确保您拥有类的所有实例,通过使构造函数
私有
并强制调用静态
方法来创建和发布实例,我将阻止直接创建实例,例如:
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);
}
}
公共类MyClass{
/**
*用于存储所有现有实例的线程安全集合
*/
私有静态最终集合实例=新ConcurrentLinkedQueue();
私有MyClass(){}
公共静态MyClass newInstance(){
//创建实例
MyClass实例=新建MyClass();
//发布实例
实例。添加(实例);
返回实例;
}
公共静态无效释放(MyClass实例){
//取消发布我的实例
实例。删除(实例);
}
公共静态void releaseAll(谓词谓词){
//取消发布与谓词匹配的所有实例
INSTANCES.stream().filter(谓词).forEach(INSTANCES::remove);
}
公共静态无效应用(消费者){
//为每个实例执行一些代码
INSTANCES.stream().forEach(使用者);
}
}
那么您的代码将是:
// 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>);
//创建我的实例
MyClass MyClass=MyClass.newInstance();
//在这里执行一些代码
...
//工作结束后释放实例以防止内存泄漏
MyClass.release(MyClass);
...
//在所有实例上执行一些代码
//在这里,它将打印所有实例
MyClass.apply(System.out::println);
...
//释放与给定测试匹配的所有实例
MyClass.releaseAll(MyClass->);
实例的“原点”是什么?你有没有举个例子?如果问题是:有没有办法检索给定类的所有实例?答案是否定的,除非您手动存储集合中使用的所有实例。我正在将其绘制到画布上,并使用(0,0)作为原点。哼哼,不是真正的线程安全。它可以使线程安全。TBH,这是第二个问题。为了不那么容易出错,对我来说,你不应该允许创建类的实例,否则你可能会错过调用add。就目前而言,YourClassRegistry只是您的类的一个集合,它应该更进一步,你同意吗?@NicolasFilotto,除了moveAll
方法,以及集合
界面中缺少所有其他方法。读者可以根据需要自由地进一步阅读。这是最有用的见解!谢谢
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>);