1、static关键字
static通常翻译成静态,可以用来修饰类、成员变量和方法,也可以声明一个静态块
1.1 static修饰类
首先需要注意的是,普通类是不能用static来修饰的,static只能用来修饰内部类。使用static修饰内部类之后可以使用“类.内部类”实例化这个内部类的对象。如下面的例子:
public static class Inner {
public Inner() {
System.out.println("this is a inner class.");
}
}
}
上面在Outer类中定义了一个静态Inner类,在Test中则直接使用了new Outer.Inner();来实例化这个内部类。
public static void main(String[] args) {
new Outer.Inner();
}
}
而对于其他非静态内部类,则只能先实例化外部类,然后才能调用内部类。 在使用static内部类时,还需要注意对于内部类,只有static声明的内部类中才能使用static声明成员变量和方法。这也是static内部类存在的必要性。 下面我介绍一下我在项目中使用过的static修饰内部类的场景。 我在一个项目中使用static修饰内部类最常用的是在定义一些各个模块中通用的信息时用到了static来修饰类。这些类中大多都是定义一些通用的变量和方法,并且多会与final结合起来使用。
1.2 static修饰变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。静态变量与实例变量的区别主要是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而实例变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
1.3 static修饰方法
static方法也叫静态方法,也可以直接使用“类.方法()”来直接调用。但是需要注意一下几点:一是静态方法中不能使用this和super关键字;二是静态方法中不能使用非静态成员变量,也不能调用非静态方法;三是静态方法与静态变量一样都是独立于任何实例,所以静态方法不能使用abstract修饰,即static方法不能为抽象方法。
1.4 static修饰静态代码块
对于静态块的使用,在我初学Java时,我是拒绝使用的,总觉得这样用不好。但是,当我在实习做项目时,通过各种调试工具分析代码时,突然发现了静态块的妙用。 首先,静态块顾名思义就是使用static{}的一段代码块。静态块是在JVM加载类的时候执行的,并且只会执行一次。由于这个特性,所以在一些场景非常好用。我在项目中遇到的过的使用场景主要有在实例化一个日志对象时,使用static块;然后就是实例化一些在类中常用但不需要多次实例化的变量等。
2、final关键字
final有不可改变之意,可用来修饰非抽象类、非抽象成员变量和方法。下面分别总结一下其用法。
2.1 final修饰类
final类不能被继承,所以其中的成员变量和方法默认也是为final的。一般来说,只有在确信该类不需要再有子类,并且不会被扩展。所以一般只有在定义一个保存一些常量信息的时候才会将类声明为final类。
2.2 final修饰变量
final修饰的变量将无法再被改变,即为常量。final变量在定义时可以不赋值,此时意味着该变量为null;在使用这个变量之前则必须为其赋值,否则会出错,赋值之后这个值将不会再被改变。
2.3 final修饰方法
final修饰的方法不能不被覆盖,所以声明为final的方法之后,该类的子类不能覆写此方法,但是可以被继承。
3、this关键字
this关键字用于引用类的当前实例。 例如:
Employees[] employees;
void manageEmployees() {
int totalEmp = this.employees.length;
System.out.println("Total employees: " + totalEmp);
this.report();
}
void report() { }
}
在上面的示例中,this关键字用于两个地方:
- this.employees.length:访问类Manager的当前实例的变量。
- this.report():调用类Manager的当前实例的方法。
此关键字是可选的,这意味着如果上面的示例在不使用此关键字的情况下表现相同。 但是,使用此关键字可能会使代码更易读或易懂。 4、super关键字 super关键字用于从子类访问父类的变量和方法。 例如:
protected int number;
protected showNumber() {
System.out.println("number = " + number);
}
}
public class Sub extends Super {
void bar() {
super.number = 10;
super.showNumber();
}
}
在上面的例子中,Sub 类访问父类成员变量 number 并调用其其父类 Super 的 showNumber() 方法。
5、注意的问题
- 在构造器中使用
super()调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。 - this、super不能用在static方法中。
- 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。
- 而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象
- 所以, this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西。