2016-11-11 84 views
-3

我有這個類實現了Cloneable。我在這裏只需要一個淺拷貝。任何人都可以在這裏指出java遵從性的問題。克隆Java中的類

public class EventSystem implements Cloneable{ 

    private String enrollmentId; 
    private String requestId; 
    private String tokenId; 
    private Date eventAt; 
    private Date loggedAt; 
    private String appCardId; 
    private String fieldKey; 
    private String fieldValue; 
    private String trsDimCardIssuerId; 
    private String trsDimCardProductId; 
    private String trsDimAppEventLocationId; 
    private String trsDimPaymentNetworkId; 
    private String trsDimAppCardTypeId; 
    private String trsTempLogId; 



    public Date getEventAt() { 
     return eventAt; 
    } 
    public void setEventAt(Date eventAt) { 
     this.eventAt = eventAt; 
    } 
    public Date getLoggedAt() { 
     return loggedAt; 
    } 
    public void setLoggedAt(Date loggedAt) { 
     this.loggedAt = loggedAt; 
    } 
    public String getRequestId() { 
     return requestId; 
    } 
    public void setRequestId(String requestId) { 
     this.requestId = requestId; 
    } 
    public String getEnrollmentId() { 
     return enrollmentId; 
    } 
    public void setEnrollmentId(String enrollemntId) { 
     this.enrollmentId = enrollemntId; 
    } 
    public String getTokenId() { 
     return tokenId; 
    } 
    public void setTokenId(String tokenId) { 
     this.tokenId = tokenId; 
    } 
    public String getTrsDimCardIssuerId() { 
     return trsDimCardIssuerId; 
    } 
    public void setTrsDimCardIssuerId(String trsDimCardIssuerId) { 
     this.trsDimCardIssuerId = trsDimCardIssuerId; 
    } 
    public String getTrsDimCardProductId() { 
     return trsDimCardProductId; 
    } 
    public void setTrsDimCardProductId(String trsDimCardProductId) { 
     this.trsDimCardProductId = trsDimCardProductId; 
    } 
    public String getTrsDimAppEventLocationId() { 
     return trsDimAppEventLocationId; 
    } 
    public void setTrsDimAppEventLocationId(String trsDimAppEventLocationId) { 
     this.trsDimAppEventLocationId = trsDimAppEventLocationId; 
    } 
    public String getTrsDimPaymentNetworkId() { 
     return trsDimPaymentNetworkId; 
    } 
    public void setTrsDimPaymentNetworkId(String trsDimPaymentNewtorkId) { 
     this.trsDimPaymentNetworkId = trsDimPaymentNewtorkId; 
    } 
    public String getTrsDimAppCardTypeId() { 
     return trsDimAppCardTypeId; 
    } 
    public void setTrsDimAppCardTypeId(String trsDimAppCardTypeId) { 
     this.trsDimAppCardTypeId = trsDimAppCardTypeId; 
    } 
    public static long getSerialversionuid() { 
     return serialVersionUID; 
    } 
    @Override 
    public Object clone() throws CloneNotSupportedException { 
      return super.clone(); 
     } 
    public String getTrsTempLogId() { 
     return trsTempLogId; 
    } 
    public void setTrsTempLogId(String trsTempLogId) { 
     this.trsTempLogId = trsTempLogId; 
    } 
    public String getAppCardId() { 
     return appCardId; 
    } 
    public void setAppCardId(String appCardId) { 
     this.appCardId = appCardId; 
    } 
    public String getFieldKey() { 
     return fieldKey; 
    } 
    public void setFieldKey(String fieldKey) { 
     this.fieldKey = fieldKey; 
    } 
    public String getFieldValue() { 
     return fieldValue; 
    } 
    public void setFieldValue(String fieldValue) { 
     this.fieldValue = fieldValue; 
    } 
} 

這裏是否存在字符串複製問題。

+1

這不是工作?什麼是錯誤? – pathfinderelite

+2

我敢肯定,在任何情況下,文檔都強烈建議不要使用clone()。如果你真的需要另一個實例,你可以實現一個拷貝構造函數。 –

+0

@pathfinderelite - 它工作正常。我唯一的問題是,它再次遵守java合規性。但這符合我淺淺複製的目的。 –

回答

1

您的字符串字段不是問題。你的日期字段是。

當您克隆的EventSystem情況下,它的每一個領域都指向完全相同的對象作爲源對象的相應字段。因此,克隆實例的enrollmentId字段指向與原始實例的enrollmentId相同的字符串對象。

但是這完全沒有問題。您可以安全地共享String對象,因爲它們是不可變的。一個String對象不能被改變。您可以更改包含String的字段的值,但String對象本身永遠不會更改。

然而,Date對象可以改變。這意味着克隆不是真正獨立於源實例。它們都引用同一個可變對象,因此如果僅爲兩個EventSystem實例之一更改該對象,則兩個實例都將看到這些更改,這可能會導致一些潛在的錯誤。考慮下面的代碼:以解決此

Calendar calendar = Calendar.getInstance(); 
calendar.set(1969, Calendar.JULY, 20, 22, 56, 0); 
Date moonLanding = calendar.getTime(); 

EventSystem e1 = new EventSystem(); 
e1.setEventAt(moonLanding); 

// Prints Sun Jul 20 22:56:00 EDT 1969 
System.out.println(e1.getEventAt()); 

EventSystem e2 = (EventSystem) e1.clone(); 

// Both e1 and e2 have references to the same Date object, so changes 
// to that Date object are seen in both objects! 
e2.getEventAt().setTime(System.currentTimeMillis()); 

// You might expect these to be different, since we only changed 
// e2.getEventAt(), but they're the same. 
System.out.println(e1.getEventAt()); 
System.out.println(e2.getEventAt()); 

的一種方式是使用一個被稱爲保護性拷貝的公共的面嚮對象的技術:

public Date getEventAt() { 
    return (eventAt != null ? (Date) eventAt.clone() : null); 
} 

public void setEventAt(Date eventAt) { 
    this.eventAt = (eventAt != null ? (Date) eventAt.clone() : null); 
} 

public Date getLoggedAt() { 
    return (loggedAt != null ? (Date) loggedAt.clone() : null) 
} 

public void setLoggedAt(Date loggedAt) { 
    this.loggedAt = (loggedAt != null ? (Date) loggedAt.clone() : null); 
} 

這防止直接修改內部日期的任何其他類領域。

另一個不那麼安全的選擇就是以克隆複製方法的日期字段:

@Override 
public Object clone() throws CloneNotSupportedException { 
    EventSystem newInstance = (EventSystem) super.clone(); 

    if (newInstance.eventAt != null) { 
     newInstance.eventAt = (Date) newInstance.eventAt.clone(); 
    } 
    if (newInstance.loggedAt != null) { 
     newInstance.loggedAt = (Date) newInstance.loggedAt.clone(); 
    } 

    return newInstance; 
}