Java修饰符用来定义类、方法、变量,通常放在语句的最前端,修饰符主要分为两类:
- 访问控制修饰符
- 非访问修饰符
访问控制修饰符
访问控制修饰符定义类、变量、方法的访问权限。Java支持4种访问控制修饰符:public, protected, default, private.
- public:修饰类、接口、方法、变量,所修饰的对象对所有类可见。
- protected:修饰变量和方法,所修饰的对象对同一包内的类可见,若子类不在同一个包内,则该子类只能访问其继承的成员。(详情见Java protected 关键字详解)
- default:修饰类、接口、方法、变量,当缺省访问控制修饰符时默认为default,所修饰的对象在同一包内可见。
- private:修饰变量和方法,所修饰的对象只在同一类内可见。用private修饰的变量不能被外部直接访问,通常需要通过getter和setter方法间接访问,实现对对象成员变量的保护。
/*Person.java------------------------------------*/
package model1;
public class Person {
private String name;
private int age;
String gender; //访问控制修饰符为default,同一包内可见
public Person(String name, int age) {
this.name = name;
this.age = age;
}
protected void setAge(int age) {
this.age = age;
}
protected int getAge() {
return this.age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
protected void sayHi() {
System.out.println("Hi");
}
}
/*Student--------------------------------------*/
package model1;
public class Student extends Person{
public Student(String name, int age) {
super(name, age);
}
public void setGender(String gender) {
this.gender = gender;//由于处于同一包内,可以访问Person的gender变量
}
}
/*Teacher------------------------------------*/
package model2;
import model1.Person;
public class Teacher extends Person {
private int klass;
public Teacher(String name, int age) {
super(name, age);
this.klass = klass;
}
public void setGender(String gender) {
this.gender = gender;//model1包内的Person的成员变量gender对model2包不可见
}
public void greet() {
super.sayHi();
}
}
/*Main.java------------------------------*/
import model1.Person;
import model1.Student;
import model2.Teacher;
public class Main {
public static void main(String[] args) {
Person student = new Student("Jason", 20);
((Student) student).setGender("male");//setGender方法来源于Student类,可以访问同一包内的gender变量
Person teacher0 = new Teacher("Jack", 30);
teacher0.sayHi();//Compile Error,Main类不在model1包中,也不是Person的子孙类,不能访问sayHi方法
Teacher teacher1 = new Teacher("John", 32);
teacher1.greet();//通过Teacher类中的greet方法访问Person的sayHi方法,Teacher类是Person类的子类,可以访问sayHi方法
}
}
区别见下表
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N详解 | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
非访问修饰符
非访问修饰符实现一些其他功能
- static 修饰符,用来修饰类方法和类变量。
static修饰的变量和方法称为静态变量和静态方法,也叫类变量和类方法,静态变量和静态方法不随着创建对象而创建,它们属于类本身所有。 - final 修饰符,用来修饰类、方法和变量。
- final修饰的类不能够被继承。
- final修饰的方法可以被继承,但是不能被子类重新定义。
- 修饰的变量为常量,是不可修改的,用final修饰的常量在创建时必须赋值。
public class Test{
final int value = 10;
// 下面是声明常量的实例
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue(){
value = 12; //将输出一个错误
}
}
- abstract修饰符,用来创建抽象类和抽象方法。
- synchronized修饰符声明的方法同一时间只能被一个线程访问。
- volatile修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
- transient 序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。