访问控制符
类的成员变量和方法都有访问权限的控制。由于类中封装了数据和代码,包中封装了类和其他的包,所以Java 提供了对类成员在四种范围中的访问权限的控制,这四种范围包括:同一个类中、同一个包中、不同包中的子类、不同包中的非子类。访问权限则包括private,protected, public 和默认。
同一个类中 | 同一个包中 | 不同包中的子类 | 不同包中的非子类 | |
---|---|---|---|---|
private | yes | |||
默认 | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
1:private
类中限定为private 的成员(域或方法)只能被这个类本身访问,即私有访问控制。它的声明如下:
private privateVar;
private privateMethod ( [paramlist] ){
⋯⋯
}
注意:同一个类的不同对象可以访问对方的private 成员变量或调用对方的private 方法,这是因为访问保护是控制在类的级别上,而不是对象的级别上。
例如,在以下程序中,三种对域 a 的访问都是可以的。
class TestPrivate
{
private int a;
void m(){
int i = a;
int j = this.a;
int k = new TestPrivate().a;
}
}
2:默认访问控制
类中的成员默认访问控制符时,称为默认访问控制。默认访问控制的成员可以被这个类本身和同一个包中的类所访问,即包访问控制。
3:protected
类中限定为protected 的成员可以被这个类本身、它的子类(包括同一个包中及不同包中的子类)及同一个包中所有其他的类访问。它的声明如下:
protected protectedVar;
protected protectedMethod ( [paramlist] ){
⋯⋯
}
注:Java 中还有一种访问控制符为private protected,它限定能被本类及其子类可以访问,而包中的其他非子类的类不能访问。
4:public
类中限定为public 的成员可以被所有的类访问。它的声明如下:
public publicVar;
public PublicMethod ( [paramlist]){
⋯⋯
}
5:类的访问控制符
在定义类时,也可以用访问控制符。类的访问控制符或者为public,或者默认。若使用public,其格式为:
public class 类名{
…
}
如果类用 public 修饰,则该类可以被其他类所访问;若类默认访问控制符,则该类只能被同包中的类访问。
6:setor 与getor
在 Java 编程中,有一种常见的做法,是将所有的或部分的域用private 修饰,从而更好地将信息进行封装和隐藏。在这样的类中,用setXXXX 和getXXXX 方法对类的属性进行存取,分别称为setor 与getor。这种方法有以下优点。
- 属性用private 更好地封装和隐藏,外部类不能随意存取和修改。
- 提供方法来存取对象的属性,在方法中可以对给定的参数的合法性进行检验。
- 方法可以用来给出计算后的值。
- 方法可以完成其他必要的工作(如清理资源、设定状态,等等)。
- 只提供getXXXX 方法,而不提供setXXXX 方法,可以保证属性是只读的。
例如:在类 Person 中将域age 以set 和get 方法提供。
class Person2
{
private int age;
public void setAge( int age ){
if (age>0 && age<200) this.age = age;
}
public int getAge(){
return age;
}
}
7:构造方法的隐藏
对于构造方法,也可用访问控制符修饰符。若构造方法默认访问控制符,则可访问包;若为public,则所有地方都可访问;若构造方法声明为private,则其他类不能生成该类的一个实例。
非访问控制符
类、域、方法可以拥有若干修饰符,包括访问控制符和非访问控制符。Java 的常用非访问控制符如,static, final, abstract 等,也可用于对类、成员进行修饰。
非 访 问 控 制 符 | 基 本 含 义 | 修 饰 类 | 修 饰 成 员 | 修饰局部变量 |
---|---|---|---|---|
static | 静态的、非实例的、类的 | 只可以修饰内部类 | Yes | |
final | 最终的、不可改变的 | Yes | Yes | Yes |
abstract | 抽象的、不可实例化的 | Yes | Yes |
1:static
在类中声明一个域或方法时,可以用static 进行修饰。格式如下:
static type classVar;
static returnType classMethod ( [paramlist] ){
⋯⋯
}
分别声明了类域和类方法。如果在声明时不用static 修饰,则声明实例变量和实例方法。
- 类域
用 static 修饰符修饰的域仅属于类的静态域,又称为静态量、类域、类变量。与此相对,不用static 修饰的域称为实例变量、实例域。
静态域是类的域,不属于任何一个类的具体对象实例。它不保存在某个对象实例的内存区间中,而是保存在类的内存区域的公共存储单元。对于该类的任何一个具体对象而言,静态域是一个公共的存储单元,任何一个类的对象访问它,取到的都是相同的数值;同样任何一个类的对象去修改它,也都是在对同一个内存单元进行操作。
静态域是公共的。
类(static)变量可以通过类名直接访问,也可以通过实例对象来访问。如我们用到的JDK 中的System 类的in 和out 对象,就是属于类的域,直接用类名来访问,即System.in 和System.out。
class Person {
static long totalNum;
int age;
String Name;
}
public class test
{
public static void main(String args[])
{
Person.totalNum=123;
Person p=new Person();
p.totalNum=100;
Person.totalNum=123;
System.out.println(p.totalNum);
}
}
输出结果为123。totalNum 代表人类的总人数,它与具体对象实例无关。可以有两种方法来访问:Person.totalNum 和p.totalNum。
- 类方法
用 static 修饰符修饰的方法仅属于类的静态方法,又称为类方法。与此相对,不用static修饰的方法,则为实例方法。类方法的本质是该方法是属于整个类的,不是属于某个实例的。
声明一个方法为 static 有以下几重含义。
- 非static 的方法是属于某个对象的方法,在这个对象创建时,对象的方法在内存中拥有自己专用的代码段。而static 的方法是属于整个类的,它在内存中的代码段将随着类的定义而进行分配和装载,不被任何一个对象专有。
- static 方法只能处理static 域或调用static方法。
- 类方法中,不能访问实例变量。在类方法中不能使用this 或super。
- 调用这个方法时,应该使用类名直接调用,也可以用某一个具体的对象名。
由于可以从类名直接访问类成员,所以访问类成员前不需要对它所在的类进行实例化。作为程序入口的main()方法必须要用static 来修饰,也是因为Java 运行时系统在开始执行一个程序前,并没有生成类的一个实例,它只能通过类名来调用main()方法作为程序的入口。
2:final
final类:如果一个类被 final 修饰符所修饰和限定,说明这个类不能被继承,即不可能有子类。
final方法:final 修饰符所修饰的方法,是不能子类所覆盖的方法。如果类的某个方法被final 修饰符所限定,则该类的子类就不能再重新定义与此方法同名的自己的方法。
即final修饰方法不可被重写,可继承,final修饰类不可被继承。
3:abstract
abstract类:抽象类,所有子类公共属性的集合,不能被实例化。抽象类不能用new 来实例化。但是抽象类可以有构造函数,构造函数可以被子类的构造函数所调用。
abstract方法:被 abstract 所修饰的方法叫抽象方法,抽象方法的作用在为所有子类定义一个统一的接口。对抽象方法只需声明,而不需实现,即用分号(;)而不是用{},格式如下:
abstract returnType abstractMethod( [paramlist] );
一旦某个类中包含了abstract 方法,则这个类必须声明为abstract 类。抽象方法在子类中必须被实现,否则子类仍然是 abstract 的。
- abstract 不能与final 并列修饰同一类。
- abstract 不能与private, static, final 或native 并列修饰同一方法。
- abstract 方法必须位于abstract 类中。
还有几个不常用的修饰符,不做过多介绍。
1.volatile 易失域
如果一个域被volatile 修饰符所修饰,说明这个域可能同时被几个线程所控制和修改,即这个域不仅仅被当前程序所掌握,在运行过程中可能存在其他未知的程序操作来影响和改变该域的取值。通常,volatile 用来修饰接受外部输入的域。如,表示当前时间的变量将由系统的后台线程随时修改,以保证程序中取到的总是最新的当前的系统时间,所以可以把它定义为易失域。
2.native 本地方法
native 修饰符一般用来声明用其他语言书写方法体并具体实现方法功能的特殊的方法,这里的其他语言包括C,C++,FORTRAN,汇编等。由于native 的方法的方法体使用其他语言在程序外部写成,所以所有的native 方法都没有方法体,而用一个分号代替。由于native 方法对应其他语言书写的模块是以非Java 字节码的二进制代码形式嵌入Java 程序的,而这种二进制代码通常只能运行在编译生成它的平台之上,所以整个Java 程序的跨平台性能将受到限制或破坏。
3.synchronized 同步方法
如果 synchronized 修饰的方法是一个类的方法(即,static 的方法),那么在被调用执行前,将把系统类Class 中对应当前类的对象加锁。如果synchronized 修饰的是一个对象的方法(未用static 修饰的方法),则这个方法在被调用执行前,将把当前对象加锁。synchronized修饰符主要用于多线程共存的程序中的协调和同步。
定义常量
public static final changliang;