类的静态成员
-全局变量、外部函数 关键字static
– 纳入到类中管理:静态成员
例3-12 对钟表类Clock进行对象计数的伪代码(模拟C/C++语言)
1 int totalClock = 0; // 模拟C++语言:定义一个全局变量,记录所创建的Clock对象个数 2 void plusObj( ) { totalClock ++; } // 模拟C/C++语言:定义一个外部函数,将计数加1 3 4 public class Clock { // 钟表类Clock 5 private int hour, minute, second; // 字段成员 6 public void set( ) { …… } // 不带参数的设置时间方法set(代码省略) 7 public void set(int h, int m, int s) { …… } // 带参数的设置时间方法set(代码省略) 8 public void show( ) { …… } // 显示时间方法show(代码省略) 9 public Clock( ) // 定义一个构造方法 10 { ……; plusObj( ); } // 希望通过构造方法为钟表对象增加计数功能 11 }
– Java语言不允许在类外定义全局变量或函数 则:
例3-13 通过静态成员实现对钟表类Clock进行对象计数的Java示意代码(Clock.java)(定义静态变量和静态方法)
1 public class Clock { // 定义钟表类Clock 2 public static int totalClock = 0; // 在定义的Clock内定义一个静态对象 字段,记录已创建的Clock对象个数 3 4 private static void plusObj() {totalClock++;} // 在定义的Clock内定义一个静态方法,将计数加1 5 private int hour, minute, second; // 字段成员 6 public void set( ) { …… } // 不带参数的设置时间方法set(代码省略) 7 public void set(int h, int m, int s) { …… } // 带参数的设置时间方法set(代码省略) 8 public void show( ) { …… } // 显示时间方法show(代码省略) 9 public Clock( ) // 定义一个构造方法 10 { ……; plusObj( ); } // 通过构造方法为钟表对象增加计数功能 11 }
1 public class ClockTest { // 测试类 2 public static void main(String[] args) { // 主方法Clock 3 c1 = new Clock( ); // 创建第一个对象 4 c1 Clock c2 = new Clock( ); // 创建第二个对象c2 5 System.out.println(Clock.totalClock); // 通过类名访问静态成员totalClock 6 System.out.println( c1 . totalClock );// 或通过任一对象引用(c1或c2)访问静态成员
System.out.println( c2 . totalClock ); 7 } 8 }
– 静态字段的内存分配
静态字段单独分配内存,并且只在加载类代码时分配一次
Clock c1 = new Clock( );//在创建对象C1时,就加载类Clock定义代码 并为静态字段totalClock创造内存单元
Clock c2 = new Clock( );
c1. totalClock、c2. totalClock 任何对象都可以像访问普通字段一样访问静态字段
Clock . totalClock 静态字段是被奔了所有字段公用的成员:类字段;可以通过类名直接方位类字段
如 hour minute都是实例字段,因为只有使用运算符new创建的对象实例才会包含普通字段
– 静态字段的语法细则
• 关键字static:在类中定义静态字段需使用关键字static进行限定,通常放在访问权限之后,数据类型之前。定义静态字段时可以初始化
• 在本类访问静态字段:在本类的方法成员中访问静态字段,直接使用字段名访问,访问时不受权限约,因为它是类的成员。这一点与访问普通字段是一样的
• 不能通过this访问静态字段:静态字段是类字段,没有包含在对象中,因此不能使用关键字this访问静态字段。这一点与访问普通字段是不一样的。注:this是指向当前对象的引用变量
• 在类外访问静态字段:在类外其他方法(例如主方法)中访问静态字段需以“类名.静态字段名”的形式访问,或通过任何一个该类对象引用以“对象引用名.静态字段名”的形式访问。类外访问静态字段受权限约束。
• 在类外访问静态字段时可以不创建对象,直接通过类名访问
Clock. totalClock 访问totalClock字段
– 静态方法的语法细则
• 关键字static:在类中定义静态方法需使用关键字static进行限定,通常放在访问权限之后,返回值类型之前
• 在本类调用静态方法:本类中的所有方法成员都可以调用静态方法。调用时直接使用方法名,并且不受访问权限约束。这一点与调用普通方法是一样的
• 在类外调用静态方法:与静态字段一样,静态方法是一种类方法,与对象实例无关。对应地,非静态的普通方法只能在创建对象实例之后才能调用,因此被称为实例方法。在类外其他方法(例如主方法)中调用静态方法,需要以“类名.静态方法名( )”的形式调用,或通过任何一个该类对象引用以“对象引用名.静态方法名( )”的形式调用。类外调用受访问权限约束。在类外调用静态方法时可不创建对象,直接通过类名调用
Clock.plusObj() 调用plusObj这个静态方法
• 静态方法访问本类其他成员:静态方法只能访问本类中的静态字段,不能访问实例字段,因为静态方法可以在没有创建任何对象的情况下直接调用,而实例字段必须在对象创建之后才会分配内存空间,因而不能访问。静态方法只能调用本类中的其他静态方法,不能调用实例方法,因为实例方法可能会间接访问实例字段
– 静态成员的应用
• 以类的形式管理全局变量或外部函数
• 将具有相同属性值的字段提炼出来,定义成静态字段,这样可以让所有对象共用同一个静态字段,从而减少内存占用。
• 将专门处理静态字段的方法定义成静态方法
例3-14 一个使用数学类Math中静态成员的演示程序
1 public class MathTest { // 测试类:测试Java语言中数学类Math的静态成员 2 public static void main(String[] args) { // 主方法 3 System.out.println("random()= " + Math.random()); // 随机数函数(静态方法) 4 System.out.println("random()= " + Math.random()); 5 System.out.println("sqrt(36)= " + Math.sqrt(36)); // 求平方根函数(静态方法) 6 System.out.println("sin(30)= " + Math.sin(30 * Math.PI / 180)); // 正弦函数(静态方法) 7 } 8 }