【问题标题】:Limit method parameter value限制方法参数值
【发布时间】:2014-06-30 23:59:18
【问题描述】:

我正在构建一个库,我的一些方法的参数应该在特定范围内。例如,在此方法中,button 应介于 1 和 3 之间:

public static void pressMouse(int button){
    try{
        Robot robot = new Robot();
        if(button == 1){
            robot.mousePress(InputEvent.BUTTON1_MASK);
        }else if(button == 2){
            robot.mousePress(InputEvent.BUTTON3_MASK);
        }else{
            robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
        }
    }catch(Exception e){

    }
}

如果值无效,有什么方法可以引发编译时错误?例如

TestLib.pressMouse(4);

我可以在方法中抛出一个异常,但如果有更好的方法会很酷。

【问题讨论】:

  • 只是一个提示,因为 Elliott 涵盖了主要思想——如果你有一组在编译时知道的给定值,那么这是对枚举的完美使用。是的,如果你最终得到大量可能的值,那可能会很尴尬。不过类型安全性很好。

标签: java methods parameters


【解决方案1】:

不像你写的那样。但是,添加这种编译时类型检查的一种方法是使用Enum Type

public enum ButtonState {
  ONE, TWO, THREE;
  public void update(Robot robot) {
    if (robot == null) return;
    if (this == ONE) {
      robot.mousePress(InputEvent.BUTTON1_MASK);
    } else if (this == TWO) {
      robot.mousePress(InputEvent.BUTTON3_MASK);
    } else {
      robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
    }
  }
}

public static void pressMouse(ButtonState button) {
  try {
    Robot robot = new Robot();
    button.update(robot);
  } catch(Exception e) {
    e.printStackTrace();
  }
}

【讨论】:

  • 这看起来可行!我会摆弄它,看看它是否能满足我的需要。谢谢!
【解决方案2】:

你不能为只能在运行时知道的东西抛出编译时错误;在这种特殊情况下,您的方法参数的值仅在运行时才知道*。您可以做的是建立方法前提条件。来自 Google Guava 的 Preconditions 之类的东西可以为您做到这一点:

Preconditions.checkArgument(button > 0 && button <= 3, "Button number must be between 1 and 3");

Elliott Frisch's answer 是另一种实现此目的的方法,但它仍然取决于来自已知来源的 button 值。也就是说,提供button 值的人也必须将其作为ButtonState enum 返回。如果不是,则必须将其转换为 ButtonState,这会产生与以前相同的问题:您不能保证您将获得合法价值(除非您的来源指定它将始终 返回合法值)。

* 这在某些语言中理论上是可行的。例如,在 Ada 中,您可以指定仅对特定范围有效的整数子类型。如果发现此方法是使用不受约束的整数类型调用的,则编译器随后会发出编译类型错误。 Java 的类型系统没有足够的表现力来做到这一点(无论如何在编译时)。但是,您必须使用已知在此范围内的值。如果您从随机来源获取值,则无法保证它会在您指定的范围内。它的值只能在运行时知道。但是,编译器至少可以警告您这是一种可能性。在 Java 中,防止这种情况的最好方法就是使用方法前置条件。但是,如果您正在使用值的已知子集,并且您同时控制这些值的源和目标,那么 enum 非常适合。

【讨论】:

  • 谢谢你的回答,不过我不想为了完成这个而进入第三方库。不过这些信息很有帮助。
  • @Nathan 如果您不想进入第三方库,一个简单的if 语句就足够了。 :) Elliot 的回答非常好,只要您可以控制 button 值的来源,或者如果您知道肯定(即方法在其文档中指定)它只会发出合法值。
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 2022-06-15
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2018-12-26
相关资源
最近更新 更多