修饰符是您添加到这些定义中以更改其含义的关键字。Java语言具有多种修饰符,包括以下内容-
Java访问修饰符
非访问修饰符
要使用修饰符,请将其关键字包含在类,方法或变量的定义中。修饰符位于语句的其余部分之前,如以下示例所示。
public class className { //...- } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { //方法主体 }
Java提供了许多访问修饰符来设置类,变量,方法和构造函数的访问级别。四个访问级别是-
包可见,默认。不需要修饰符。
仅对类可见(私有)。
对全局(公共)可见。
对包和所有子类可见(受保护)。
默认访问修饰符意味着我们不会为类,字段,方法等显式声明访问修饰符。
声明为没有任何访问控制修饰符的变量或方法可用于同一包中的任何其他类。接口中的字段隐式为public static final,而接口中的方法默认为public。
可以在没有任何修饰符的情况下声明变量和方法,如以下示例所示:
String version = "1.5.1"; boolean processOrder() { return true; }
声明为私有的方法,变量和构造函数只能在声明的类本身内访问。
专用访问修饰符是最严格的访问级别。类和接口不能是私有的。
如果在类中存在公共获取方法,则可以在类外部访问声明为私有的变量。
使用private修饰符是对象封装自身并从外界隐藏数据的主要方式。
以下类使用私有访问控制-
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }
在这里,Logger类的format变量是私有的,因此其他类无法直接检索或设置其值。
因此,为了使此变量可用于外部世界,我们定义了两个公共方法:getFormat()和setFormat(String),setFormat返回值format的值,setFormat(String)设置其值。
可以从任何其他类访问声明为public的类,方法,构造函数,接口等。因此,可以从属于Java Universe的任何类中访问在公共类内声明的字段,方法,块。
但是,如果我们尝试访问的公共类位于不同的包中,则仍然需要导入公共类。由于类继承,类的所有公共方法和变量均由其子类继承。
以下功能使用公共访问控制-
public static void main(String[] arguments) { //...- }
申请的main()
方法必须是公开的。否则,Java解释器(例如java)将无法调用它来运行该类。
在超类中声明为受保护的变量,方法和构造函数只能由其他包中的子类或受保护成员类的包中的任何类访问。
受保护的访问修饰符不能应用于类和接口。方法,字段可以声明为受保护,但是接口中的方法和字段不能声明为受保护。
受保护的访问使子类有机会使用helper方法或变量,同时防止无关的类尝试使用它。
以下父类使用受保护的访问控制,以允许其子类覆盖openSpeaker()方法-
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { //实施细节 } } class StreamingAudioPlayer { boolean openSpeaker(Speaker sp) { //实施细节 } }
在这里,如果我们将openSpeaker()
方法定义为私有,那么除AudioPlayer之外,其他任何类都无法访问该方法。如果我们将其定义为公共的,那么所有外部世界都可以使用它。但是我们的目的是仅将此方法公开给它的子类,因此才使用受保护的修饰符。
继承方法的以下规则被强制执行-
在超类中声明为public的方法还必须在所有子类中都是public。
在超类中声明为protected的方法必须在子类中受保护或公开;他们不能是私有的。
声明为private的方法根本不会继承,因此没有规则。
Java提供了许多非访问修饰符来实现许多其他功能。
用于创建类方法和变量的 static 修饰符。
用于最终确定类、方法和变量的实现的 final 修饰符。
用于创建抽象类和方法的 abstract 修饰符。
用于线程的 synchronized 和 volatile 修饰符。
静态变量
在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修饰符通常与static一起使用,以使常数成为类变量。
public class Test { final int value = 10; //以下是声明常量的示例: public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue() { value = 12; // will give an error } }
final方法
最终方法不能被任何子类覆盖。如前 ,final修饰符可防止在子类中修改方法。
使方法最终化的主要目的是,方法的内容不应由外部人员更改。
您可以在类声明中使用 final修饰符声明方法,如以下示例所示:
public class Test { public final void changeName() { //方法主体 } }
final类
使用被声明为 final的类的主要目的是防止该类被子类化。如果将一个类标记为final,则任何类都不能从final类继承任何功能。
public final class Test { //类主体 }
抽象类
抽象类永远无法实例化。如果将一个类声明为抽象类,则其唯一目的是扩展该类。
一个类不能同时是抽象类和最终类(因为不能扩展最终类)。如果一个类包含抽象方法,则该类应声明为抽象。否则,将引发编译错误。
抽象类可以同时包含抽象方法和常规方法。
abstract class Caravan { private double price; private String model; private String year; public abstract void goFast(); // an abstract method public abstract void changeColor(); }
抽象方法
抽象方法是声明的没有任何实现的方法。方法主体(实现)由子类提供。抽象方法决不能是最终的或严格的。
任何扩展抽象类的类都必须实现超类的所有抽象方法,除非子类也是抽象类。
如果一个类包含一个或多个抽象方法,则必须将该类声明为abstract。抽象类不需要包含抽象方法。
抽象方法以分号结尾。示例:public abstract sample()
;
public abstract class SuperClass { abstract void m(); // abstract method } class SubClass extends SuperClass { //实现抽象方法 void m() { ...--...... } }
同步修饰符
sync关键字用于指示一种方法一次只能由一个线程访问。同步修改器可以与四个访问级别修改器中的任何一个一起应用。
public synchronized void showDetails() { ...--.... }
瞬态修饰符
实例变量被标记为瞬态,以指示JVM在序列化包含它的对象时跳过特定变量。
该修饰符包含在创建变量的语句中,该语句位于变量的类或数据类型之前。
public transient int limit = 55; // will not persist public int b; // will persist
volatile修饰符
volatile修饰符用于让JVM知道访问该变量的线程必须始终将其自身的变量私有副本与内存中的主副本合并。
访问volatile变量将同步主存储器中变量的所有缓存副本。可变变量只能应用于对象类型或私有类型的实例变量。volatile对象引用可以为null。
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) { // line 1 //一些代码在这里 } } public void stop() { active = false; // line 2 } }
通常,在一个线程(使用Runnable开始的那个线程)中调用run(),从另一个线程调用stop()。 如果在第1行中使用了操作的缓存值,则在第2行中将active设置为false时,循环可能不会停止,这就是您要使用volatile的时候。