Java对象引用问题?
我有以下课程Java对象引用问题?,java,builder,object-reference,builder-pattern,Java,Builder,Object Reference,Builder Pattern,我有以下课程 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){
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;
}
公共类有效负载{
私人地图;
公共静态负载实例=新负载();
专用有效载荷(){
map=新的HashMap();
}
公共有效负载put(字符串键、对象值){
map.put(键、值);
归还这个;
}
公共地图getMap(){
返回图;
}
}
公共类AjaxRequestBinder{
私有字符串url;
私有字符串方法;
私有地图数据;
私有字符串数据类型;
公共AjaxRequestBinder(字符串url、字符串方法、有效负载、AjaxDataType数据类型){
this.url=url;
这个方法=方法;
this.data=payload!=null?payload.getMap():payload.INSTANCE.getMap();
this.dataType=dataType!=null?dataType.name():AjaxDataType.html.name();
}
//…getters()和setters()
}
公共列表getSampleAjaxBinders()引发异常{
List requestBinders=new ArrayList();
add(新的AjaxRequestBinder(getEndpointURL(ServiceModule.CAT),HttpMethod.GET.name(),null,AjaxDataType.json));
add(新的AjaxRequestBinder(getEndpointURL(ServiceModule.DOG),HttpMethod.GET.name(),null,AjaxDataType.json));
add(新的AjaxRequestBinder(getEndpointURL(ServiceModule.CHICKEN),HttpMethod.GET.name(),null,AjaxDataType.json));
add(新的AjaxRequestBinder(getEndpointURL(ServiceModule.GOAT),HttpMethod.GET.name(),null,AjaxDataType.json));
add(新的AjaxRequestBinder(getEndpointURL(ServiceModule.RABBIT)、HttpMethod.POST.name()、buildPayload(ServiceModule.RABBIT、HttpMethod.POST)、AjaxDataType.json));
返回活页夹;
}
公共有效负载buildPayload(ServiceModule模块,HttpMethod HttpMethod)引发异常{
有效载荷=Payload.INSTANCE;
模块=模块!=null?模块:ServiceModule.NONE;
if(httpMethod.equals(httpMethod.POST)){
开关(模块){
案例类别:{
//无所事事
}中断;
个案犬:{
//无所事事
}中断;
个案鸡:{
//无所事事
}中断;
个案山羊:{
//无所事事
}中断;
病例兔:{
有效载荷。放置(“颜色”、“白色”)。放置(“动作”、“跳跃”);
}中断;
}
}否则{
抛出新的NotYetImplementedException();
}
返回有效载荷;
}
但由于某种奇怪的原因,当调用方法getSampleAjaxBinders()
时,它返回一个AjaxRequestBinder
对象列表,其中每个对象都有
data={“color”:“white”,“action”:“hops”}
然而,这仅适用于最后添加的项目。所有先前添加的项都应该只有数据={}
(空映射)。当我逐步调试该方法时,我发现一切正常,直到调用buildPayload(ServiceModule模块,HttpMethod HttpMethod)
,然后自动覆盖列表中先前添加的项目中的空映射
有人能给我解释一下,是什么导致了这里出现的这种奇怪的对象引用问题 之所以会发生这种情况,是因为您总是使用
有效负载的单个实例,而该实例恰好是为RABBIT
设置的
您的buildPayload
方法返回设置为共享实例的payload
:
Payload payload = Payload.INSTANCE;
同时,当您将null
有效负载传递给AjaxRequestBinder
构造函数时,构造函数使用相同的有效负载。实例
:
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
方法中的映射。之所以会发生这种情况,是因为您始终使用Payload
的单个实例,而该实例恰好被设置为RABBIT
您的buildPayload
方法返回设置为共享实例的payload
:
Payload payload = Payload.INSTANCE;
同时,当您将null
有效负载传递给AjaxRequestBinder
构造函数时,构造函数使用相同的有效负载。实例
:
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
方法中的映射。payload.getMap()
和payload.instance.getMap()
是完全相同的对象。列表中只有一个映射。重复的映射并不能真正回答这个问题,因为在这种情况下,添加到集合中的所有对象都是不同的。问题归结为无意中使用共享实例来代替空实例,这与重复实例不同。投票重新打开问题。payload.getMap()
和payload.INSTANCE.getMap()
是完全相同的对象。列表中只有一个映射。重复的映射并不能真正回答这个问题,因为在这种情况下,添加到集合中的所有对象都是不同的。问题归结为无意中使用共享实例来代替空实例,这与重复实例不同。表决重新开始问题。