2016-11-11 82 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; 
}