2016-11-11 16 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を保持するフィールドの値を変更できますが、Stringオブジェクト自体は決して変更できません。

ただし、Dateオブジェクトに変更されます。これは、クローンが本当にソースインスタンスから独立していないことを意味します。どちらも同じ変更可能なオブジェクトを参照するので、2つのEventSystemインスタンスのうちの1つだけそのオブジェクトが変更された場合、両方のインスタンスに変更が反映され、潜在的なバグが発生する可能性があります。このコードを考えてみます。これは、直接内部の日付を修正するから、他のクラスを防止

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); 
} 

:これを解決する

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()); 

一つの方法は、守備のコピーとして知られている一般的なオブジェクト指向技術を使用することですフィールド。

別の、より少ない安全なオプションは、あなたのcloneメソッドで日付フィールドのクローンを作成することです:

@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; 
} 
関連する問題