簡體   English   中英

Java對象參考問題?

[英]Java Object Reference Problems?

我有以下課程;

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) ,然后它會自動覆蓋列表先前添加的項目中的空映射。

有人可以給我解釋一下這里出現的這個奇怪的對象引用問題的原因嗎?

發生這種情況的原因是,您始終只使用一個Payload實例,而該實例恰好是為RABBIT設置的。

您的buildPayload方法返回設置為共享實例的payload

Payload payload = Payload.INSTANCE;

同時,當您將null有效負載傳遞給AjaxRequestBinder構造函數時,該構造函數使用相同的Payload.INSTANCE

this.data = payload != null ? payload.getMap() : Payload.INSTANCE.getMap();

您可以通過以下方式解決此問題:將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();

請注意,如果繼續上述共享實例方法,則需要在buildPayload方法中清除映射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM