2016-11-10 69 views
1

我有一個單例對象,我需要分配API REST返回的對象,而當我這樣做時沒有任何修改。如何將從API REST檢索的對象分配給單例類?

辛格爾頓:

public class Stations { 
    private static Stations instance = null; 
    private List<Station> stations; 
    private Stations() { 
     // Exists only to defeat instantiation. 
    } 
    public static Stations getInstance() { 
     if(instance == null) { 
     instance = new Stations(); 
     } 
     return instance; 
    } 
    public List<Station> getStations(){ 
     return this.stations; 
    } 
} 

呼叫:

public class StationsCall implements Job { 
    private Stations stations = Stations.getInstance(); 
    Client client = ClientBuilder.newClient(); 
    public void execute(JobExecutionContext context) throws JobExecutionException { 

     WebTarget targetGet = client.target("http://wservice.viabicing.cat/v2/stations"); 
     this.stations = targetGet.request(MediaType.APPLICATION_JSON_TYPE).get(new GenericType<Stations>(){}); 
    } 
    public List<Station> getStations(){ 
     List<Station> aux = this.stations.getStations(); 
     return aux; 
    } 
} 
+0

您正在使用'私人車站車站=新車站();'這裏。這創建了一個實例,但與單例實例不同。使用'Stations.getInstance()'代替 – AxelH

+0

對不起,我現在編輯的代碼,它不工作。 – Fr33d0m

+0

'this.stations = targetGet.request ...'會收到單例引用?似乎你每次重新創建一個新的「Stations」,這是奇怪的有一個私人構造... – AxelH

回答

2

調用this.stations = targetGet.request(...)只能修改類StationsCall領域stations,它不會修改實際的單身人士,你應該甚至無法創建一個Stations的實例,因爲它的構造函數是private

你需要的是一個設置器在你的單身,以設置當前的電臺列表。

事情是這樣的:

public class Stations { 
    // Use an AtomicReference to make sure that all threads see the last list of stations 
    private final AtomicReference<List<Station>> stations = new AtomicReference<>(); 
    private Stations() { 
     // Exists only to defeat instantiation. 
    } 
    public static Stations getInstance() { 
     // Lazy create your instance of Stations using a static inner class 
     // for thread safety 
     return StationsHolder.INSTANCE; 
    } 
    public List<Station> getStations(){ 
     // Get the last list of stations from the AtomicReference 
     return this.stations.get(); 
    } 

    public void setStations(List<Station> stations) { 
     // Set the new list of stations and make it unmodifiable for thread safety 
     this.stations.set(Collections.unmodifiableList(stations)); 
    } 

    private static class StationsHolder { 
     private static final Stations INSTANCE = new Stations(); 
    } 
} 

注:我提高你的代碼,使其線程安全的,一個單必須通過併發線程使用好機會。

然後你StationsCall類將是:

public void execute(JobExecutionContext context) throws JobExecutionException { 
    ... 
    Stations.getInstance().setStations(targetGet.request(...)); 
} 

public List<Station> getStations(){ 
    return Stations.getInstance().getStations(); 
} 

假設你真正需要的是讓站的當前列表只集中其訪問的能力,你不如果不在乎是單身或沒有,那麼你的代碼,而應該是:

public class Stations { 
    // Use an AtomicReference to make sure that all threads see the last instance 
    private static final AtomicReference<Stations> INSTANCE = 
     new AtomicReference<>(new Stations()); 
    private List<Station> stations; 

    public Stations() { 
    } 

    public Stations(final List<Station> stations) { 
     // Make a safe and unmodifiable copy of the list of stations 
     this.stations = Collections.unmodifiableList(new ArrayList<>(stations)); 
    } 

    public static Stations getInstance() { 
     return INSTANCE.get(); 
    } 

    public List<Station> getStations(){ 
     return this.stations; 
    } 

    public static void setInstance(Stations stations) { 
     // Set the new instance 
     INSTANCE.set(new Stations(stations.getStations())); 
    } 
} 

然後你StationsCall類將是:

public void execute(JobExecutionContext context) throws JobExecutionException { 
    ... 
    Stations.setInstance(targetGet.request(...)); 
} 

public List<Station> getStations(){ 
    return Stations.getInstance().getStations(); 
} 
+0

好多了!但是這行可能仍然是一個問題'this.stations = targetGet.request ...' – AxelH

+0

@AxelH是的,我的確在這裏假設'targetGet.request(...)'返回'Station'的List,但是我不要相信它應該很難做到這一點,我只是在這裏關注最初的問題,即*如何將從API REST獲得的對象分配給單例類?* –

+0

因爲即使它不是很安全,他的代碼應該可以工作(或者我錯過了什麼?) – AxelH