[英]Java Object Reference Problems?
I have the following classes; 我有以下课程;
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;
}
But for some odd reason, when method getSampleAjaxBinders()
is called, it returns a list of AjaxRequestBinder
objects with each and every one of them having; 但是出于某种奇怪的原因,当调用方法
getSampleAjaxBinders()
,它将返回一个AjaxRequestBinder
对象的列表,其中每个对象都有;
data = {"color":"white", "action":"hops"}
whereas this is required for only the last added item. 而只有最后添加的项目才需要这样做。 All the previously added items should simply have
data = {}
(empty map). 先前所有添加的项目都应仅具有
data = {}
(空映射)。 When I step-debug through the method, I find out that all is well until buildPayload(ServiceModule module, HttpMethod httpMethod)
is called which then automatically overwrites the empty maps in the previously added items of the list. 当我逐步调试该方法时,我发现一切都很好,直到
buildPayload(ServiceModule module, HttpMethod httpMethod)
,然后它会自动覆盖列表先前添加的项目中的空映射。
Can somebody please explain to me what might be responsible for this odd object reference problems being exhibited here; 有人可以给我解释一下这里出现的这个奇怪的对象引用问题的原因吗?
This happens because you always use a single instance of Payload
, which happens to be set for RABBIT
. 发生这种情况的原因是,您始终只使用一个
Payload
实例,而该实例恰好是为RABBIT
设置的。
Your buildPayload
method returns payload
which is set to the shared instance: 您的
buildPayload
方法返回设置为共享实例的payload
:
Payload payload = Payload.INSTANCE;
At the same time, when you pass null
payload to AjaxRequestBinder
constructor, the constructor uses the same Payload.INSTANCE
: 同时,当您将
null
有效负载传递给AjaxRequestBinder
构造函数时,该构造函数使用相同的Payload.INSTANCE
:
this.data = payload != null ? payload.getMap() : Payload.INSTANCE.getMap();
You can fix it either by making Payload
constructor public and creating new instances in buildPayload
, or making a separate empty instance of Payload
for using in cases when null
is supplied to AjaxRequestBinder
constructor: 您可以通过以下方式解决此问题:将
Payload
构造函数公开,并在buildPayload
创建新实例,或者将Payload
单独设置为空实例,以在向AjaxRequestBinder
构造函数提供null
情况下使用:
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();
Note that if you continue with the shared instance approach above, you would need to clear the map in the buildPayload
method. 请注意,如果继续上述共享实例方法,则需要在
buildPayload
方法中清除映射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.