我有以下课程;
public class Payload{
private Map<String, Object> map;
public static Payload INSTANCE = new Payload();
private Payload(){
map = new HashMap<>();
}
public Payload put(String key, Object value){
map.put(key, value);
return this;
}
public Map<String, Object> getMap(){
return map;
}
}
public class AjaxRequestBinder {
private String url;
private String method;
private Map<String, Object> data;
private String dataType;
public AjaxRequestBinder(String url, String method, Payload payload, AjaxDataType dataType) {
this.url = url;
this.method = method;
this.data = payload != null ? payload.getMap() : Payload.INSTANCE.getMap();
this.dataType = dataType != null ? dataType.name() : AjaxDataType.html.name();
}
//... getters() & setters()
}
public List<AjaxRequestBinder> getSampleAjaxBinders() throws Exception {
List<AjaxRequestBinder> requestBinders = new ArrayList<>();
requestBinders.add(new AjaxRequestBinder(getEndpointURL(ServiceModule.CAT), HttpMethod.GET.name(), null, AjaxDataType.json));
requestBinders.add(new AjaxRequestBinder(getEndpointURL(ServiceModule.DOG), HttpMethod.GET.name(), null, AjaxDataType.json));
requestBinders.add(new AjaxRequestBinder(getEndpointURL(ServiceModule.CHICKEN), HttpMethod.GET.name(), null, AjaxDataType.json));
requestBinders.add(new AjaxRequestBinder(getEndpointURL(ServiceModule.GOAT), HttpMethod.GET.name(), null, AjaxDataType.json));
requestBinders.add(new AjaxRequestBinder(getEndpointURL(ServiceModule.RABBIT), HttpMethod.POST.name(), buildPayload(ServiceModule.RABBIT, HttpMethod.POST), AjaxDataType.json));
return requestBinders;
}
public Payload buildPayload(ServiceModule module, HttpMethod httpMethod) throws Exception {
Payload payload = Payload.INSTANCE;
module = module != null ? module : ServiceModule.NONE;
if(httpMethod.equals(HttpMethod.POST)){
switch(module){
case CAT:{
// Do nothing
}break;
case DOG:{
// Do nothing
}break;
case CHICKEN:{
// Do nothing
}break;
case GOAT:{
// Do nothing
}break;
case RABBIT:{
payload.put("color", "white").put("action", "hops");
}break;
}
}else{
throw new NotYetImplementedException();
}
return payload;
}
但是由于一些奇怪的原因,当调用方法getSampleAjaxBinders()
时,它返回AjaxRequestBinder
个对象的列表,每个对象都有;
data = {"color":"white", "action":"hops"}
而这只是最后添加的项目所必需的。之前添加的所有项目都应该只有data = {}
(空地图)。当我通过该方法进行步骤调试时,我发现在调用buildPayload(ServiceModule module, HttpMethod httpMethod)
之前一切都很好,然后自动覆盖先前添加的列表项中的空映射。
有人可以向我解释一下这个奇怪的物体参考问题可能会对这个问题负责吗?
答案 0 :(得分:4)
这是因为您总是使用Payload
的单个实例,恰好是为RABBIT
设置的。{/ p>
您的buildPayload
方法返回设置为共享实例的payload
:
Payload payload = Payload.INSTANCE;
同时,当您将null
有效负载传递给AjaxRequestBinder
构造函数时,构造函数使用相同的Payload.INSTANCE
:
this.data = payload != null ? payload.getMap() : Payload.INSTANCE.getMap();
您可以通过将Payload
构造函数公开并在buildPayload
中创建新实例,或者在Payload
的情况下创建null
的单独空实例来解决此问题。提供给AjaxRequestBinder
构造函数:
public static final Payload INSTANCE = new Payload();
// Add this line to Payload
public static final Payload EMPTY = new Payload();
...
// Use EMPTY payload when the caller does not supply an actual one:
this.data = payload != null ? payload.getMap() : Payload.EMPTY.getMap();
请注意,如果您继续使用上述共享实例方法,则需要使用buildPayload
方法清除地图。