static
static描述一个类中独立于对象的域或方法。
static可以修饰类中的字段、代码块、方法,修饰后表示类里面与对象无关的数据或方法,所以有称作类数据或类方法。
class StaticTest {
static int num = 12;
}
StaticTest s1 = new StaticTest();
StaticTest s2 = new StaticTest();
在上面代码中,s1.num与s2.num指向统一存储空间,值都是12,如果s1.num改变,则s2.num也会改变。
this
this只能用于方法内部,表示当前对象的引用。
class Banana {
int weight = 100; // 100g
void peel() {
// ... 剥开皮
}
void eat(String person) {
// ... 吃
peel();
this.weight--
}
}
在eat()方法中,weight需要递减,但我们不知道需要操作Banana类的哪个对象实例?其实,编译器会把”所操作对象的引用“暗自传递给类中的每一个方法,如下:
Banana ba = new Banana();
Banana.eat(ba, "yawn");
所以,eat方法有一个隐含的参数ba,是Banana类的实例。关键字this就表示这个隐含的实例,所以this只能用在方法内部。
eat方法调用peel方法时,也可以写成this.peel(),但是无此必要,编译器会自动添加。所以,只有当需要明确指出当前对象的引用时,才需要使用this。
如果需要让方法返回当前的对象,可以使用this,这样可以进行链式的调用。如下:
Banana eat(String person) {
// ... 吃
peel();
this.weight--;
return this;
}
Banana ba = new Banana();
ba.eat("yawn").eat("yawn").eat("yawn");
使用this调用构造器,this必须放在其他构造器代码的最前面,如下:
class Flower {
int id;
String name;
Flower(String name) {
this.name = name;
}
Flower(int id, String name) {
this(name);
this.id = id;
}
}
上面例子也展示了this的另一个常见用法:方法中参数名与字段名相同时,使用this.xxx表示字段名,避免歧义。
final
final 在java中表示不可变。
用到final有三种情况:数据、方法和类。
final 数据
final修饰基本数据用来告知编译器,这块数据时恒定不变的,也就是一个编译时常量。编译器可以将这个常量带入任何可能用到的计算中,可以减轻运行时的负担。
final修饰对象的引用时,表示引用不会改变,但并不保证对象本身不变。也就是一旦被初始化指向一个对象,就不能将它指向另一个对象了。
空白final(blank final)
空白final也就是未初始化的final域,但是编译器会确保这个final域在使用前被初始化。如下:
class Test {
final int i; // blank final
public Test() {
i = 1; // 如果未在构造器中初始化,编译就会报错
}
}
必须在域的定义处,或者每个构造器中对空白final进行初始化,这就保证了blank final域在使用前总能被初始化。
final参数
java允许将方法参数声明为final,表明无法在方法中改变该引用所指向的对象。
也就是可以读参数,但无法修改参数。
final方法
final表示吧方法锁定,防止任何继承类修改它。
private 的方法都隐式的被指定为final的,因为继承类无法继承private方法。
final类
final类表示不允许任何人继承该类,或者处于安全考虑,不希望它有任何子类。
但是final类的域可以为final或不是final的,但其中的方法都被隐式指定为final的,因为没有类可以覆盖它。