java 为什么 bean 验证 Min/Max 约束不支持 double 类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7422803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:54:28  来源:igfitidea点击:

Why do bean validation Min/Max constraints not support the double type?

javaconstraintsprecisionbean-validation

提问by Manuel Leuenberger

Could somebody please explain to me why the JPA supports the doubletype as a field type, but the bean validation constaints in javax.validation.constraints(i.e. @Min/@Max) do not support it? I know documentation says this is due to rounding errors, but if I choose the field type to be doubleI already admit that I don't care that much about the explicit precision.

有人可以向我解释为什么 JPA 支持该double类型作为字段类型,但javax.validation.constraints(即@Min/ @Max)中的 bean 验证约束不支持它?我知道文档说这是由于舍入错误造成的,但是如果我选择字段类型是,double我已经承认我不太关心显式精度。

The scenario I ran into this dilemma is the following: I have an Entity that represents a point on the earth's surface. If the precision is within a few centimeters it's fine. It looks something like this:

我遇到这个困境的场景如下:我有一个代表地球表面上一个点的实体。如果精度在几厘米以内,那就没问题了。它看起来像这样:

@Entity
public class Point {

    /**
     * The longitude in radians.
     */
    @Min(-Math.Pi)
    @Max(Math.Pi)
    double longitude;
    /**
     * The latitude in radians.
     */
    @Min(-Math.Pi / 2)
    @Max(Math.Pi / 2)
    double latitude;

}

Unfortunately this does not work, because the annotations do not support the double type. But using BigDecimalinstead is not really an option, because I have some extensive computation with multiple points going on that still needs to be reasonably fast. I worked around it by defining a custom constraint check that does work with doubles, but somehow I think there is something I'm missing in the whole story. So, what am I missing?

不幸的是,这不起作用,因为注释不支持双精度型。但是使用BigDecimal代替并不是一个真正的选择,因为我有一些广泛的计算,需要进行多个点,但仍然需要相当快。我通过定义一个适用于doubles的自定义约束检查来解决它,但不知何故,我认为在整个故事中我遗漏了一些东西。那么,我错过了什么?

采纳答案by Ralph

It is because of rounding. But not because of the problem that a double is may not correct enough to express the number you want. It is more that the annotation value (of Minand Max) is of type long, so it can not express any number with decimal places. On the other hand you can not use a double to express exact all numbers that a long can express.

这是因为四舍五入。但不是因为 double 可能不够正确以表达您想要的数字的问题。更何况注解值(ofMinMax)是long类型的,所以不能表示任何带小数的数字。另一方面,您不能使用 double 来表达 long 可以表达的所有数字。

So the API designers had to decide for one of the two ways (long or double)

所以 API 设计者必须决定两种方式中的一种(长或双)

回答by Rodrigo Araujo

Use the @DecimalMinannotation. You will need to pass a literal String value, because the attrubute valuemust be constant (String.valueOf(- Math.PI)) doesn't work. It works to validate Double attributes.

使用@DecimalMin注释。您将需要传递文字字符串值,因为属性value必须是常量 (String.valueOf(- Math.PI)) 不起作用。它用于验证 Double 属性。

@DecimalMin(value = "0.01", message = "Your message...")
private Double longitude;