Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将从API REST检索到的对象分配给单例类?_Java_Rest_Jersey_Singleton - Fatal编程技术网

Java 如何将从API REST检索到的对象分配给单例类?

Java 如何将从API REST检索到的对象分配给单例类?,java,rest,jersey,singleton,Java,Rest,Jersey,Singleton,我有一个单例对象,需要分配API REST返回的对象,这样做时不会修改任何内容 单身人士: public class Stations { private static Stations instance = null; private List<Station> stations; private Stations() { // Exists only to defeat instantiation. } public static Sta

我有一个单例对象,需要分配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;
   }
}
公共类电台{
私有静态站实例=null;
私人名单站;
私人电台(){
//存在只是为了阻止实例化。
}
公共静态站点getInstance(){
if(实例==null){
实例=新站点();
}
返回实例;
}
公共广播电台名单(){
把这封信寄回车站;
}
}
电话:

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;
    }
}
公共类StationCall实现作业{
专用站点=Stations.getInstance();
Client Client=ClientBuilder.newClient();
public void execute(JobExecutionContext上下文)引发JobExecutionException{
WebTarget targetGet=client.target(“http://wservice.viabicing.cat/v2/stations");
this.stations=targetGet.request(MediaType.APPLICATION_JSON_TYPE).get(新的GenericType(){});
}
公共广播电台名单(){
List aux=this.stations.getStations();
返回aux;
}
}

调用
this.stations=targetGet.request(…)
只修改类
StationsCall
的字段
stations
,它不修改实际的单例,您甚至不能创建
stations
的实例,因为它的构造函数是
私有的

您需要的是在单例中设置一个setter,以设置当前电台列表

大概是这样的:

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

假设您真正需要的是能够将当前的站点列表仅集中到其访问,并且您不关心它是否是单例,那么您的代码应该是:

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

您正在使用
专用电台=新电台()这里。这将创建一个实例,但与singleton实例不同。使用
Stations.getInstance()
代替抱歉,我现在编辑了代码,但它无论如何都不起作用。
this.Stations=targetGet.request…
将接收单例引用吗?似乎你每次都会重新创建一个新的
站点,有一个私有构造函数是很奇怪的…我想没有…什么?好的,
targetGet
应该如何处理singleton?在这里看不到任何插入的
站点
,因此总是会有一个空列表。更好!但是这行代码可能仍然有问题,
this.stations=targetGet.request…
@AxelH是的,我确实在这里假设
targetGet.request(…)
返回一个
列表,其中包含
,但我不认为这应该很难做到,这里我只关注最初的问题,即如何将从API REST获取的对象分配给singleton类?因为,即使它不是真正安全的,他的代码也应该工作(或者我错过了什么?@AxelH如果您可以创建一个新实例并重新设置它,那么它就不再是一个singleton,因此没有他的代码不能工作,由于
站点
有一个
私有
构造函数,因此在解析JSON内容时不可能创建
站点
的实例,他必须使用包装器类来获取列表并应用我在这里提出的建议
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()));
    }
}
public void execute(JobExecutionContext context) throws JobExecutionException {
    ...
    Stations.setInstance(targetGet.request(...));
}

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