null
类型是Object
吗?
class C {
int i;
String s;
public C() {}
}
s
总是null
吗?
简单类型如int
怎么样?那会是什么?零或任意值?
方法中的局部变量怎么样?
public void meth() {
int i;
}
i
的酉值是什么?
然而,依赖于此类默认值通常被视为不良 编程风格。
好的,你建议我们做什么?
class A {
String s = "";
int i = 0;
}
OR:
class A {
String s;
int i;
public A() {
// default constructor
s = "";
i = 0;
}
}
哪个更好,为什么?
答案 0 :(得分:27)
来自太阳java tutorial
并不总是需要指定一个 声明字段时的值。字段 声明但未初始化的声明 将被设置为合理的默认值 编译器。一般来说,这个 默认值为零或null, 取决于数据类型。依靠 但是,这样的默认值是 一般认为编程不好 风格。
以下图表总结了 上述数据的默认值 类型。
Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
boolean false
String (or any object) null
局部变量略有不同 不同;编译器永远不会分配 未初始化的默认值 局部变量。如果你不能 初始化你的局部变量在哪里 它被声明,请务必分配它 尝试使用它之前的值。 访问未初始化的本地 变量将导致编译时 错误。
答案 1 :(得分:4)
对于成员变量: String的默认值为null。基元的默认值为0(浮点值为0.0)。
对于局部变量: 您必须在使用之前显式初始化本地变量。
关于你问题的第二部分:
您始终可以在成员变量定义中说String s = "";
,或在构造函数中说s = "";
。然后你知道它将具有非null值。 (另外,在你的setter中你需要确保有人不会尝试将其设置为null。)
答案 2 :(得分:3)
字段:对象默认为null;整数,多头和空头到0;字符串为null;布尔要假。这都是here。
编译器将强制您自己初始化方法中声明的变量局部变量。
答案 3 :(得分:2)
原始字段初始化为0
/ false
。对象初始化为null
。但坦率地说,你可以试过那个......
答案 4 :(得分:1)
关于setter方法问题:setter的重点是它们可以检查传递的对象是否符合类的要求。 e.g。
public void setS(String s) {
if (s == null)
throw new IllegalArgumentException("S must not be null");
this.s = s;
}
或者,使用Google Collections / Google Guava:
public void setS(String s) {
this.s = Preconditions.checkNotNull(s, "S must not be null");
}
当然,您可以定义任意约束,例如:
/**
* Sets the foo. Legal foo strings must have a length of exactly 3 characters.
*/
public void setFoo(String foo) {
if (foo == null)
throw new IllegalArgumentException("Foo must not be null");
if (foo.length() != 3)
throw new IllegalArgumentException("Foo must have exactly 3 characters");
...
当然在这种情况下,总是在setter和/或类的JavaDoc中为属性指定正确的值范围。
答案 5 :(得分:0)
JLS 4.12.5. Initial Values of Variables
每个类变量,实例变量或数组组件为 在创建时用默认值初始化(第15.9节,第15.20.2节)
对于字节类型,默认值为零,即 (字节)0。
对于short类型,默认值为零,即 (短)0。
对于int类型,默认值为零,即0。
对于long类型,默认值为零,即0L。
对于float类型,默认值为正零,即0.0f。
对于double类型,默认值为正零,即0.0d。
对于char类型,默认值为空字符,即 '\ u0000'。
对于布尔类型,默认值为false。
对于所有引用类型(第4.3节),默认值为null。