有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何通过setter设置最终字段?

我有以下简称课程:

public class Employee {

    private final float pointPosition;

    public Employee(float pointPosition) {
        this.pointPosition = pointPosition;
    }

}

我想检查构造函数传入的pointPosition,以确保它不超过1.0

我尝试将赋值移动到它自己的私有setter方法,该方法执行前提条件检查,但显然这给了我一个错误,因为我正在构造函数之外重新分配final字段

我可以将构造函数更改为:

public Employee(float newPointPosition) {
    verifyPointPosition(newPointPosition); //Will throw
    this.pointPosition = pointPosition;
}

但我更喜欢用自己的方法把它整齐地包装起来

我的选择是什么


共 (2) 个答案

  1. # 1 楼答案

    选项1:不要让它成为最终选项

    你不能让它成为最后一场比赛,也不能让二传成为私人赛


    选项2:在构造函数中进行检查和设置

    这就是你已经展示的


    选项3:黑客方式

    你可以通过反射设置最终变量,但是我绝对不推荐这样做,除非你被迫这么做


    我会选择第二种 如果担心构造函数太乱,可以创建其他构造函数并将其设置为私有,例如:

    public class MyClass {
        private final float variable;
    
        public MyClass(float variable) {
            this();
            if(variable < 0.0f || 1.0f < variable)
                throw new IllegalArgumentException("'variable' has to be between 0.0 and 1.0");
            this.variable = variable;
        }
    
        private MyClass() {
            //Set everything else
        }
    }
    

    实际上,这段代码不会编译

  2. # 2 楼答案

    我建议通过将参数段落包装在构造函数的单个方法调用中来实现这一点

    你还没有说你想要什么行为,如果值无效是否抛出异常,或者是否只是将其清理为正常值,但无论哪种方式都可以:

    public class Employee
      private static final float MAX_POSITION = 1.0f;
      private final float pointPosition;
    
      public Employee(float pointPosition) {
        this.pointPosition = sanitizePointPosition(pointPosition);
      }
    

    然后你有两个选择:

    1. 抛出异常:

      private float sanitizePointPosition(float pointPosition) {
        if(pointPosition > MAX_POSITION) {
          throw new IllegalArgumentException("Point position must be <= "
                     + MAX_POSITION + ", it was: " + pointPosition);
        }
        return pointPosition;
      }
      
    2. 将该值设置为正常值

      private float sanitizePointPosition(float pointPosition) {
        return pointPosition > MAX_POSITION ? MAX_POSITION : pointPosition;
      }