Java 非访问修饰符
Java提供了许多非访问修饰符,用于实现许多其他功能。
- 使用static修饰符创建类方法和变量。
-
使用final修饰符对类、方法和变量进行终结实现。
-
使用abstract修饰符创建抽象类和方法。
-
使用synchronized和volatile修饰符处理线程。
静态修饰符
静态变量
使用static关键字创建独立于类的任何实例存在的变量。不论类的实例有多少个,静态变量只存在一个副本。
静态变量也被称为类变量。局部变量不能声明为静态变量。
静态方法
使用static关键字创建独立于类的任何实例存在的方法。
静态方法不使用定义在其所属类对象中的任何实例变量。静态方法从参数中获取所有的数据,并根据这些参数计算结果,不引用任何变量。
类变量和方法可以通过类名加点和变量或方法名进行访问。
示例
static修饰符用于创建类方法和变量,如下例所示−
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " + InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i) {
new InstanceCounter();
}
System.out.println("Created " + InstanceCounter.getCount() + " instances");
}
}
这将产生以下结果 –
输出
Started with 0 instances
Created 500 instances
final修饰符
final变量
final变量只能被显式地初始化一次。final修饰的引用变量永远不能重新赋值,它不能引用一个不同的对象。
不过,对象内部的数据可以被修改。因此,对象的状态可以改变,但引用不可以。
对于变量,final修饰符通常与static一起使用,将常量变为类变量。
示例
public class Test {
final int value = 10;
// The following are examples of declaring constants:
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue() {
value = 12; // will give an error
}
}
final方法
final方法不能被任何子类覆盖。正如先前提到的,final修饰符防止方法在子类中被修改。
将方法声明为final的主要意图是方法的内容不应该被任何外部人改变。
示例
您可以在类声明中使用final修饰符声明方法,如下面的示例中所示:
public class Test {
public final void changeName() {
// body of method
}
}
final类
使用被声明为final的类的主要目的是防止该类被子类化。如果一个类被标记为final,则其他任何类都不能从这个final类中继承任何特性。
例子
public final class Test {
// body of class
}
抽象修饰符
抽象类
抽象类无法实例化。如果一个类声明为抽象类,则其唯一目的是让其他类继承它。
一个类不能同时是抽象类和最终类(因为最终类无法被继承)。如果一个类包含抽象方法,则该类应该声明为抽象类,否则将引发编译错误。
抽象类既可以包含抽象方法也可以包含普通方法。
示例
abstract class Caravan {
private double price;
private String model;
private String year;
public abstract void goFast(); // an abstract method
public abstract void changeColor();
}
抽象方法
抽象方法是指在没有任何实现的情况下声明的方法。方法的具体实现应由子类提供。抽象方法不能是final或strict。
任何继承抽象类的类都必须实现超类的所有抽象方法,除非子类本身也是抽象类。
如果一个类包含一个或多个抽象方法,则该类必须声明为抽象类。抽象类不需要包含抽象方法。
抽象方法以分号结尾。例如:public abstract sample();
示例
public abstract class SuperClass {
abstract void m(); // abstract method
}
class SubClass extends SuperClass {
// implements the abstract method
void m() {
.........
}
}
synchronized修饰符
使用synchronized关键字表示一个方法一次只能被一个线程访问。synchronized修饰符可以与任何四种访问级别修饰符一起使用。
示例
public synchronized void showDetails() {
.......
}
transient修饰符
实例变量被标记为transient,以指示JVM在序列化包含该变量的对象时跳过特定变量。
这个修饰符包含在创建变量的语句中,紧跟在变量的类或数据类型之前。
示例
public transient int limit = 55; // will not persist
public int b; // will persist
volatile修饰符
volatile修饰符用于告诉JVM,访问该变量的线程必须将自己的私有副本与内存中的主副本合并。
访问volatile变量会同步所有缓存副本和主内存中的变量。volatile只能应用于实例变量,即对象类型或private类型。volatile对象引用可以为null。
示例
public class MyRunnable implements Runnable {
private volatile boolean active;
public void run() {
active = true;
while (active) { // line 1
// some code here
}
}
public void stop() {
active = false; // line 2
}
}
通常情况下,run()方法在一个线程中被调用(你使用Runnable启动的线程),而stop()方法则在另一个线程中被调用。如果在第一行中使用了active的缓存值,那么当你在第二行将active设置为false时,循环可能不会停止。这时候你应该使用volatile关键字。