2013-03-04 107 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,它本身是不可变的......但是有人甚至可以使用反射来使该字段不是最终的。
所以这个类不可变的,但它是不能破的
而且没有办法绕过它。