2013-03-04 31 views
1

我正在開發一個不可變類。下面是我的不可變類,請告訴我這是完全不可變的,或者如果我失去了一些東西或它的不可變性可以通過無論如何細分,然後請大家指教..關於不可變類完整功能

public final class ImmutableReminder{ 
    private final Date remindingDate; 

    public ImmutableReminder (Date remindingDate) { 
     if(remindingDate.getTime() < System.currentTimeMillis()){ 
      throw new IllegalArgumentException("Can not set reminder」 + 
         「 for past time: " + remindingDate); 
     } 
     this.remindingDate = new Date(remindingDate.getTime()); 
    } 

    public Date getRemindingDate() { 
     return (Date) remindingDate.clone(); 
    } 
} 
+1

從我的角度來看,沒關係:)但是不要忘記檢查null – Taras 2013-03-04 14:54:18

+0

構造函數已經檢查'null' ...暗含地:-) – 2013-03-04 15:26:41

回答

2

您應該根據您的類不變量進行檢查,然後複製remindingDate.getTime()。否則,對提醒日期進行引用的攻擊者可能會調用其上的.set方法,以便在檢查其有效性後更改該值。

long time = remindingDate.getTime();

public final class ImmutableReminder{ 
    private final Date remindingDate; 

    public ImmutableReminder (Date remindingDate) { 
     long incomingTime = remindingDate.getTime() 

     if(incomingTime < System.currentTimeMillis()){ 
      throw new IllegalArgumentException("Can not set reminder」 + 
         「 for past time: " + remindingDate); 
     } 
     this.remindingDate = new Date(incomingTime); 
    } 

    public Date getRemindingDate() { 
     return (Date) remindingDate.clone(); 
    } 
} 
+0

請問你能更新代碼嗎 – user2129402 2013-03-04 15:00:55

+0

爲什麼downvote?這是對的。 – Jazzepi 2013-03-04 15:01:09

+0

@ user2129402更新 – Jazzepi 2013-03-04 15:11:08

-1

如果它是完整的類,它是確實是不可變的。

0

這個類是你通常所說的不變的。
但是你說「或者它的不變性可以被無論如何地分解」......在java中,反射可以打破所有的規則。一些真正的邪惡的人可以檢測到你的私人最終提醒日期,並改變它,使其首先可訪問,然後調用setter。 你可以使用更好的Date實現,比如joda time DateTime,它本身是不可變的......但是有人甚至可以使用反射來使該字段不是最終的。
所以這個類不可變的,但它是不能破的
而且沒有辦法繞過它。