1

对你们来说,这似乎是一个愚蠢的问题,但我是一个 java 菜鸟,仍然试图掌握整个概念。所以,我基本上有一个简单的剧院管理系统,允许我将组添加到数据库中。对于每个组,您可以添加每个具有唯一学生 ID 和名称的学生。您还可以将排练日期添加到组中。这两个都存储在单独的链表中。这是我的排练对象:

public Rehearsal(int d, int m, int y) {
    day = d;
    month = m;
    year = y;
}

这是组类中的 addRehearsal 方法:

public void addRehearsal(int d, int m, int y) {
    Rehearsal newrehearsal = new Rehearsal(d, m, y);
    if (!RehearsalDates.contains(newrehearsal)) {
        RehearsalDates.add(newrehearsal);
    }
    else
        JOptionPane.showMessageDialog(null, "Rehearsal already exists for this group!", "Error", JOptionPane.WARNING_MESSAGE);
}

我的问题是,我如何以及在哪里可以限制可以输入的值。这意味着,如果为 int d > 31 或 int m > 12 输入的值,程序会以消息对话框的形式给出错误。这对于年份来说并不是必需的,因为允许用户创建排练日期过去和未来。

谢谢你们的帮助:)

4

2 回答 2

2

Validating dates is more complex than checking each parameter. For example, calling it with (29, 2, 2000) would be invalid (recall that 2000 was not a leap year), even though all parameters are "within range".

The only sane way to check is to attempt to parse a Date from the parameters and catch the exception. There are a couple of ways to do this, but the simplest is this:

public Rehearsal(int d, int m, int y) {
    try {
        sdf = new SimpleDateFormat("d-M-yyyy");
        sdf.setLenient(false);
        sdf.parse(d + "-" + m + "-" + y);
    } catch (ParseException e) {
        // the parameters are not valid
    }
    // rest of code
}

Note the call to setLenient(), which is required, otherwise invalid input "rolls over" to the next available valid date - for example 36-12-2012 would be parsed as 05-01-2013.

The best place to put this code would be in the constructor, throwing an exception:

public Rehearsal(int d, int m, int y) {
    try {
        sdf = new SimpleDateFormat("d-M-yyyy");
        sdf.setLenient(false);
        sdf.parse(d + "-" + m + "-" + y);
    } catch (ParseException e) {
        // the parameters are not valid
        throw new IllegalArgumentException();
    }
    day = d;
    month = m;
    year = y;
}

And you would catch this wherever it is called.

Rehearsal newrehearsal;
try {
    newrehearsal = new Rehearsal(1, 2, 3);            
} catch (IllegalArgumentException ex) {
    JOptionPane.showMessageDialog(null, "Invalid date input!", "Error", JOptionPane.WARNING_MESSAGE);
    return;
}
// rest of method

An even better design would be to pass a Date object, putting the onus on the caller to validate input, and there would be less throw and catch code.

于 2013-04-07T20:24:08.253 回答
0

为什么不IllegalArgumentException从构造函数中抛出一个Rehearsal然后在addRehearsal方法中捕获它:

public Rehearsal(int d, int m, int y) {
    if (d < 1 || d > 31) {
        throw new IllegalArgumentException("Invalid day");
    }
    if (m < 1 || m > 12) {
        throw new IllegalArgumentException("Invalid month");
    }
    day = d;
    month = m;
    year = y;
}

并在addRehearsal方法中捕获构造异常:

Rehearsal newrehearsal;
try {
    newrehearsal = new Rehearsal(1, 2, 3);            
} catch (IllegalArgumentException ex) {
    JOptionPane.showMessageDialog(null, "Invalid date input!", "Error", JOptionPane.WARNING_MESSAGE);
    return;
}

这应该是一个中间解决方案 - 它肯定会防止创建无效日期。

然后,您可能希望稍后在输入上添加侦听器,以首先防止无效数据。

最后,您可能要考虑使用Calendar而不是自定义日期对象。

于 2013-04-07T20:09:58.660 回答