Java 检查是否已设置基元
给定一个非常简单的类:Java 检查是否已设置基元,java,primitive,Java,Primitive,给定一个非常简单的类: class MyClass { int id; double value; MyClass(int id) { this.id = id; } void setValue(double v) { value = v; } boolean isValueUnassigned() { return value == 0; } } 要检查值是否尚未赋值,只需执
class MyClass {
int id;
double value;
MyClass(int id) {
this.id = id;
}
void setValue(double v) {
value = v;
}
boolean isValueUnassigned() {
return value == 0;
}
}
要检查
值
是否尚未赋值,只需执行返回值==0即可
由于默认情况下double
是0
,那么,yes原语double
默认设置为0.0
。但是如果你只做返回值==0
您无法确定之前是否有人调用了setValue(0)
,但这也是一个有效的赋值。如果您想100%确定是否有人调用了setValue()
,我建议这样做:
class MyClass {
private int id;
private double value;
private boolean valueSet; // is false by default
public MyClass(int id) {
this.id = id;
}
public void setValue(double v) {
value = v;
valueSet = true;
}
public boolean isValueSet() {
return valueSet;
}
}
您应该使用double的包装器类,即double。对于双数据类型,默认值为null。这样就不会有任何歧义。如果值为null,则不会为其分配任何值。默认情况下,双精度值为0,但您可以将-1传递给它
double value=-1代码>
检查:
if (value!= -1) {
// To Do
}
再加上@Harshal已经说过的话。类似的代码如下所示:
class MyClass {
private int id;
private Double value;
public MyClass(int id) {
this.id = id;
}
public void setValue(double v) {
value = v;
}
public double getValue() {
//Check for null pointer and return
if(value == null)
return <whatever you want>;
return value.doubleValue();;
}
public boolean isValueSet() {
return (value == null ? false : true);
}
}
class-MyClass{
私有int-id;
私人双重价值;
公共MyClass(内部id){
this.id=id;
}
公共无效设置值(双v){
值=v;
}
公共双getValue(){
//检查空指针并返回
如果(值==null)
返回;
返回值。doubleValue();;
}
公共布尔值isValueSet(){
返回值(值==null?false:true);
}
}
可以使用Double重新初始化Double,方法如下
解释
这里的主要问题是,无论您选择什么double
值,例如0
或-1
,它实际上都可能是用户设置的有效值。在这种情况下,您的应用程序将错误地返回它尚未设置,而它已被设置
您需要的是一个哨兵值,即表示这种情况的特殊值。通常有3种方法:
旗帜
引入一个简单的布尔标志boolean isSet
,一旦设置,您将其初始化为false
,并设置为true
这种方法很好,速度也很快。但是,如果您(例如)开始引入数百个需要表示“尚未设置”的值,则无法很好地扩展
对象包装器
除实际值/实例外,对象变量还可以引用null
。这可以用作指示特殊情况的哨兵
因此,您可以在内部将值表示为Double
,而不是Double
,从null
开始
缺点是,与简单的原语相比,对象引入了相当多的内存和性能开销。在这种情况下,这并不重要,但如果你将其扩大到数千个,你肯定会开始感受到影响
Double value = null;
void setValue(double value) {
this.value = value; // auto-boxing
}
boolean isValueUnassigned() {
return value == null;
}
标记值
如果您的应用程序自然地允许某些值永远不能使用,那么您可以使用它们作为指示案例的哨兵。一个常见的例子是age
字段,您不允许用户将其设置为负值。然后您可以使用,例如-1
来指示它
这种方法非常普遍和有效。但它显然并不总是适用的,也不一定是最可读/可维护的方法
double value = -1;
void setValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Negative values are not allowed");
}
this.value = value;
}
boolean isValueUnassigned() {
return value == -1;
}
double value=-1;
无效设置值(双值){
如果(值<0){
抛出新的IllegalArgumentException(“不允许使用负值”);
}
这个值=值;
}
布尔值isValueUnassigned(){
返回值==-1;
}
找到了最干净、最清晰的表达方式:
class MyClass {
int id;
Optional<Double> value;
MyClass(int id) {
this.id = id;
this.value = Optional.empty();
}
void setValue(double v) {
value = Optional.of(v);
}
double getValue() {
if (isValueUnassigned) {
throw new RuntimeException("Value has not been assigned");
}
return value.get();
}
boolean isValueUnassigned() {
return value.isEmpty();
}
}
class-MyClass{
int-id;
可选值;
MyClass(内部id){
this.id=id;
this.value=可选的.empty();
}
无效设置值(双v){
值=可选值(v);
}
双getValue(){
如果(isValueUnassigned){
抛出新的RuntimeException(“未分配值”);
}
返回值。get();
}
布尔值isValueUnassigned(){
返回值;
}
}
创建对象时会指定该值。您不需要使用方法检查值是否已赋值,因为答案总是肯定的。如果我这么做是什么意思?是否要使用if语句检查值是否等于零?是。没关系。原语double
初始化为0
。但是,可以显式初始化变量。这被认为是良好的做法。如果我理解正确,您将检查双精度是否已更改。。。。问题是当0是一个有效值时,有人可以设置0。。。与检查方法相比,典型的方法是使用哨兵值(如附加的布尔isSet
标志)或使用包装器对象(如Double
)作为内部表示,它可以使用null
作为哨兵值来指示这一点。而且,只有在应用程序允许的情况下,才能指定一个永远不能用作sentinel的值。例如-1
或年龄
字段的任何其他负值。但是用户可以故意将该值设置为-1
。任何double
值都可以用作有效值,但它们不能安全地用作哨兵。虽然这是一个选项,但它牺牲了相当多的内存和速度,用于一些也可以以不同方式解决的问题,例如使用一个简单的布尔isSet
标志。@Zabuza不会添加额外的变量,因为这会使它变得混乱吗?只是想知道…视情况而定。在这种情况下,我会说它是好的(这是一个简单的类)。但总的来说,我同意。我只是想把它留作一个注释。注意,使用可选的作为字段是不好的。这违背了它的预期用途和设计。这是一个缺陷,不应该这样做。见和。可能存在一些罕见的边缘情况
double value = -1;
void setValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Negative values are not allowed");
}
this.value = value;
}
boolean isValueUnassigned() {
return value == -1;
}
class MyClass {
int id;
Optional<Double> value;
MyClass(int id) {
this.id = id;
this.value = Optional.empty();
}
void setValue(double v) {
value = Optional.of(v);
}
double getValue() {
if (isValueUnassigned) {
throw new RuntimeException("Value has not been assigned");
}
return value.get();
}
boolean isValueUnassigned() {
return value.isEmpty();
}
}