检查原语是否已设置
Check if primitive has been set
给出一个很简单的class:
class MyClass {
int id;
double value;
MyClass(int id) {
this.id = id;
}
void setValue(double v) {
value = v;
}
boolean isValueUnassigned() {
return value == 0;
}
}
要检查 value
是否还没有被分配,如果我只做 return value == 0;
可以吗,因为默认情况下 double
是 0
?
嗯,是的,原始 double
默认设置为 0.0
。但是如果你只是做 return value == 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 使用包装器 class,它是 Double。对于 Double 数据类型,默认值为空。这样就不会有歧义了。如果值为 null,则不会为其分配任何值。
double 值默认为 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);
}
}
You can use Double to reinitialize the double using following
class MyClass {
int id;
Double value;
MyClass(int id) {
this.id = id;
}
void setValue(Double v) {
value = v;
}
boolean isValueUnassigned() {
return value == null ? false : true;
}
}
说明
这里的主要问题是,无论您选择什么 double
值,例如0
或 -1
,它实际上可以是用户设置的有效值。在这种情况下,您的应用程序会错误地 return 它尚未设置,而实际上它已设置。
您需要的是 标记值,即指示这种情况的特殊值。通常有 3 种方法:
旗帜
引入一个简单的布尔标志 boolean isSet
,您将其初始化为 false
并在设置后设置为 true
。
这种方法很好而且非常快。但是,如果您开始引入数百个需要表示 "not set yet".
的此类值,则无法很好地扩展
double value;
boolean isValueSet = false;
void setValue(double value) {
this.value = value;
isValueSet = true;
}
boolean isValueUnassigned() {
return !isValueSet;
}
对象包装器
对象变量除了它们实际的 values/instances 之外还可以引用 null
。这可以作为哨兵来指示特殊情况。
因此您可以将值在内部表示为 Double
而不是 double
,从 null
.
开始
缺点是与简单的原语相比,对象会引入相当多的内存和性能开销。在这种情况下,这并不重要,但如果将其扩展到数千个,您肯定会开始感受到影响。
Double value = null;
void setValue(double value) {
this.value = value; // auto-boxing
}
boolean isValueUnassigned() {
return value == null;
}
哨兵值
如果您的应用程序自然允许某些值永远不能使用,您可以将它们用作标记来指示这种情况。一个常见的例子是 age
字段,您不允许用户将其设置为负值。那么就可以使用,比如-1
来表示。
这种方法很常见也很有效。但它显然并不总是适用,也不一定是最readable/maintainable的方法。
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();
}
}
创建对象时赋值。您不需要一种方法来检查值是否已分配,因为答案总是肯定的。
给出一个很简单的class:
class MyClass {
int id;
double value;
MyClass(int id) {
this.id = id;
}
void setValue(double v) {
value = v;
}
boolean isValueUnassigned() {
return value == 0;
}
}
要检查 value
是否还没有被分配,如果我只做 return value == 0;
可以吗,因为默认情况下 double
是 0
?
嗯,是的,原始 double
默认设置为 0.0
。但是如果你只是做 return value == 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 使用包装器 class,它是 Double。对于 Double 数据类型,默认值为空。这样就不会有歧义了。如果值为 null,则不会为其分配任何值。
double 值默认为 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);
}
}
You can use Double to reinitialize the double using following
class MyClass {
int id;
Double value;
MyClass(int id) {
this.id = id;
}
void setValue(Double v) {
value = v;
}
boolean isValueUnassigned() {
return value == null ? false : true;
}
}
说明
这里的主要问题是,无论您选择什么 double
值,例如0
或 -1
,它实际上可以是用户设置的有效值。在这种情况下,您的应用程序会错误地 return 它尚未设置,而实际上它已设置。
您需要的是 标记值,即指示这种情况的特殊值。通常有 3 种方法:
旗帜
引入一个简单的布尔标志 boolean isSet
,您将其初始化为 false
并在设置后设置为 true
。
这种方法很好而且非常快。但是,如果您开始引入数百个需要表示 "not set yet".
的此类值,则无法很好地扩展double value;
boolean isValueSet = false;
void setValue(double value) {
this.value = value;
isValueSet = true;
}
boolean isValueUnassigned() {
return !isValueSet;
}
对象包装器
对象变量除了它们实际的 values/instances 之外还可以引用 null
。这可以作为哨兵来指示特殊情况。
因此您可以将值在内部表示为 Double
而不是 double
,从 null
.
缺点是与简单的原语相比,对象会引入相当多的内存和性能开销。在这种情况下,这并不重要,但如果将其扩展到数千个,您肯定会开始感受到影响。
Double value = null;
void setValue(double value) {
this.value = value; // auto-boxing
}
boolean isValueUnassigned() {
return value == null;
}
哨兵值
如果您的应用程序自然允许某些值永远不能使用,您可以将它们用作标记来指示这种情况。一个常见的例子是 age
字段,您不允许用户将其设置为负值。那么就可以使用,比如-1
来表示。
这种方法很常见也很有效。但它显然并不总是适用,也不一定是最readable/maintainable的方法。
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();
}
}
创建对象时赋值。您不需要一种方法来检查值是否已分配,因为答案总是肯定的。