Java:如何限制传递给方法的参数值

6
假设我有一个方法,它需要一个整数作为参数,假设该方法只接受值为0、1、2而不接受其他整数。有没有一种方法可以“强制”该方法只接受0、1、2呢?

5
如果参数无效,当然可以始终抛出IllegalArgumentException异常。 - Jon Skeet
1
你可以使用AOP(面向切面编程),例如AspectJ库:创建一些注释,指示其中一个参数应受限制,并创建与该注释匹配的Joinpoint,以及创建检查该值的Advice。但是-这只会进行运行时检查。如果您想要静态的、编译时的检查,则需要创建自己的数据类型。 - Erwin Bolwidt
3个回答

8

您需要创建一个自定义数据类型,该数据类型仅能接受值为012,不能使用普通的int

在这种情况下,您可以使用枚举类型enum

enum ZeroOneOrTwo {
    ZERO(0),
    ONE(1),
    TWO(2);
    public final int val;
    private ZeroOneOrTwo(int val) {
        this.val = val;
    }
}

并将其用于以下模式:

void myMethod(ZeroOneOrTwo arg) {
    System.out.println("Int value: " + arg.val);
}

如果你被强制要求以int作为参数(例如,如果你正在实现一个接口),则可以在给定值超出范围时抛出IllegalArgumentException。但通常情况下,你会希望让编译器捕获这个问题,而不是在运行时处理它。


但是如果您更改枚举的顺序,那么枚举的序号将会被破坏。 - dragon66
如果方法应该接受0、1或2,很可能它们实际上代表的不是数量,此时ZERO、ONE和TWO将具有更具描述性的名称,其中顺序是无关紧要的。 - aioobe
@aioobe 请问aioobe,我不确定如何使用该枚举来表示3个整数。 - Lisa Anne
1
@aioobe 还是不明白 :-((,也许在你删除构造函数之前更清楚了。 - Lisa Anne
1
回退到使用构造函数和枚举字段的方法。 - aioobe
你可以添加一个名为valueOf(int)的方法,在该方法中抛出IllegalArgumentException,并在原始方法中使用它来接收一个int - Jin Kwon

2
也许不是每种情况都适用(但您没有进一步说明您想要实现什么,因此也许值得一试),但也许您可以考虑创建三个方法而不是一个方法?或者使用继承,因为您正在使用面向对象的语言?
例如,不是将一些信息编码到整数中,改变它可能会更好的编程风格。
所以,而不是...
void addEmployee(int type) {
    switch(type) {
        case 0: // add regular eymploee
        case 1: // add manager
        case 2: // add CEO
    }
}

考虑以下情况:

void addRegularEmployee() { 
    // ... 
}
void addManager() { 
    // ... 
}
void addCEO() { 
    // ... 
}

...甚至可能会出现...

void add(Employee e) {
    // ...
}

1

正如 @JonSkeet 评论所说,您可以抛出 IllegalArgumentException 的实例。虽然我找不到翻译 the way to force 的方法。

void giveMeZeroOneOrTwo(final int value) {

    if (value != 0 && value != 1 && value != 2) {
        throw new IllegalArgumentException("unacceptable value: " + value);
    }

    // now you can read the method name, huh?
}

或者Bean Validation可能适合您。
void giveMeZeroOneOrTwo(@Min(0) @Max(2) final int value) {
}

好的,使用枚举可能是一个不错的方法,我很喜欢这个。

enum Magic {
    ONE(1),
    TWO(2),
    THREE(3);
    public static Magic valueOf(int value) {
        for (final Magic v : values()) {
            if (v.value == value) {
                return v;
            }
        }
        throw new IllegalArgumentException("undefined value: " + value);
    }
    private Magic(int value) {
        this.value = value
    }
    private final int value;
}

现在可以验证接受一个 int 的方法。
void giveMeOneTwoOrThree(final int value) {
    // still throws an IllegalArgumentException
    final Magic magic = Magic.valueOf(value);
}

方法很明显:通过构建一个只有三个不同值的类型,使该限制对类型系统可见。这正是基于枚举的方法所实现的。 - Marko Topolnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接