使用Java中的getter函数返回可变成员变量(Date/Timestamp)?

Yu *_*aao 2 java getter findbugs

我有一个java类:

class MyObj{
  private Timestamp myDate;

  public  Timestamp getMyDate(){ 
       return mydate;
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

当我通过Findbugs检查时,它说:

错误类型和模式:EI - EI_EXPOSE_REP可以通过返回对可变对象的引用来公开内部表示

那么,用Java 编写getterfor DateTimestamp类型的更好方法是什么?

T.J*_*der 8

Date并且Timestamp都是可变的,因此返回对您的引用Timestamp意味着调用者可以更改类的内部状态.如果这是一个问题,这只是一个问题,如果这是有道理的; 如果你的意思是调用者能够修改你的对象的状态(通过修改你正在返回的实例字段的状态),那没关系,尽管它可能是相对微妙的错误的来源.但是,通常情况下,您并不意味着允许呼叫者这样做; 因此FindBugs将其标记出来.

如果您想避免公开对可变对象的引用,您有几个选择:

  1. 返回时克隆对象("防御性副本"),以便调用者获得副本,而不是原始副本:

    public Timestamp getMyDate(){ 
         return new Timestamp(mydate.getTime());
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 返回不可变类型或基元而不是可变类型,例如:

    public long getMyDate(){ 
         return mydate.getTime();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 根本不要使用可变对象.例如Timestamp,您可以使用LocalDateTimeZonedDateTime来自java.time,例如:

    class MyObj{
      private LocalDateTime myDate;
    
      public LocalDateTime getMyDate(){ 
           return mydate;
      }
      // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果您需要更新类中的日期(让我们使用添加一天的示例),而不是更改对象,则将其替换为新对象:

    this.mydate = this.myDate.plusDays(1);
    
    Run Code Online (Sandbox Code Playgroud)


Sur*_*tta 6

返回防御副本而不是原始副本,以便getter访问者无法修改您的实际时间戳.

 public Timestamp getMyDate(){ 
       return new Timestamp(mydate.getTime());
  }
Run Code Online (Sandbox Code Playgroud)