2016-09-23 59 views
4

我想創建一個靜態方法,將所有實例移動到原點,但我不能在實例變量(如xPosition和yPosition)上使用靜態方法。我如何使在Java中的所有實例做點什麼

我需要遍歷所有的實例,還是有辦法用靜態方法做到這一點?

在此先感謝!

+0

什麼是你稱爲實例的「起源」?你有一個例子嗎? – AxelH

+0

如果問題是:是否有辦法檢索給定類的所有實例?答案是否定的,除非您手動存儲集合中使用的所有實例。 –

+0

我正在繪製到畫布並使用(0,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>); 
+0

最有用的見解!謝謝!! –

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(); 

這可以讓你有單獨的「實例」組,您可以單獨移動。

全局可變狀態(如註冊表的靜態版)是在頸部疼痛,減少了可測試性,需要更多的關愛與尊重線程安全等

+0

嗡嗡聲不是線程安全的 –

+1

它可以使線程安全。 TBH,這是次要的問題。 –

+0

更不容易出錯,對我來說,你不應該允許創建YourClass的實例,否則你可能會錯過調用add。就目前而言,YourClassRegistry只不過是某種收藏YourClass罷了,它應該走得更遠,你不同意嗎? –

相關問題