2016-11-11 4 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 клонированного экземпляра указывает на тот же объект String, что и исходный экземпляр enrollmentId.

Но это нормально. Вы можете безопасно обмениваться объектами String, потому что они неизменяемы. Объект String не может быть изменен. Вы можете изменить значение поля, содержащего String, но сам объект String никогда не изменится.

Однако, объекты даты могут быть изменены. Это означает, что клон действительно не зависит от исходного экземпляра. Они оба относятся к одному и тому же изменяемому объекту, поэтому, если этот объект изменен только для одного из двух экземпляров 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); 
} 

Это предотвращает любые другие классы от непосредственного изменения внутренней Даты поле.

Другой, менее безопасным вариантом является клонировать поля Date в вашем методе клонирования:

@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; 
} 
Смежные вопросы