分享
 
 
 

JAVA静态变量

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

JAVA的静态变量相当于类字段,而不用理解为对象字段。

Static Fields and Methods

In all sample programs that you have seen, the main method is tagged with the static modifier. We are now ready to discuss the meaning of this modifier.

Static Fields

If you define a field as static, then there is only one such field per class. In contrast, each object has its own copy of all instance fields. For example, let's suppose we want to assign a unique identification number to each employee. We add an instance field id and a static field nextId to the Employee class:

class Employee

{

. . .

private int id;

private static int nextId = 1;

}

Now, every employee object has its own id field, but there is only one nextId field that is shared among all instances of the class. Let's put it another way. If there are one thousand objects of the Employee class, then there are one thousand instance fields id, one for each object. But there is a single static field nextId. Even if there are no employee objects, the static field nextId is present. It belongs to the class, not to any individual object.

In most object-oriented programming languages, static fields are called class fields. The term "static" is a meaningless holdover from C++.

Let's implement a simple method:

public void setId()

{

id = nextId;

nextId++;

}

Suppose you set the employee identification number for harry:

harry.setId();

Then the id field of harry is set, and the value of the static field nextId is incremented:

harry.id = . . .;

Employee.nextId++;

Constants

Static variables are quite rare. However, static constants are more common. For example, the Math class defines a static constant:

public class Math

{

. . .

public static final double PI = 3.14159265358979323846;

. . .

}

You can access this constant in your programs as Math.PI.

If the keyword static had been omitted, then PI would have been an instance field of the Math class. That is, you would need an object of the Math class to access PI, and every object would have its own copy of PI.

Another static constant that you have used many times is System.out. It is declared in the System class as:

public class System

{

. . .

public static final PrintStream out = . . .;

. . .

}

As we mentioned several times, it is never a good idea to have public fields because everyone can modify them. However, public constants (that is, final fields) are ok. Since out has been declared as final, you cannot reassign another print stream to it:

out = new PrintStream(. . .); // ERROR--out is final

If you look at the System class, you will notice a method setOut that lets you set System.out to a different stream. You may wonder how that method can change the value of a final variable. However, the setOut method is a native method, not implemented in the Java programming language. Native methods can bypass the access control mechanisms of the Java language. This is a very unusual workaround that you should not emulate in your own programs.

Static Methods

Static methods are methods that do not operate on objects. For example, the pow method of the Math class is a static method. The expression:

Math.pow(x, y)

computes the power xy. It does not use any Math object to carry out its task. In other words, it has no implicit parameter.

In other words, you can think of static methods as methods that don't have a this parameter.

Because static methods don't operate on objects, you cannot access instance fields from a static method. But static methods can access the static fields in their class. Here is an example of such a static method:

public static int getNextId()

{

return nextId; // returns static field

}

To call this method, you supply the name of the class:

int n = Employee.getNextId();

Could you have omitted the keyword static for this method? Yes, but then you would need to have an object reference of type Employee to invoke the method.

It is legal to use an object to call a static method. For example, if harry is an Employee object, then you can call harry.getNextId() instead of Employee.getnextId(). However, we find that notation confusing. The getNextId method doesn't look at harry at all to compute the result. We recommend that you use class names, not objects, to invoke static methods.

You use static methods in two situations:

When a method doesn't need to access the object state because all needed parameters are supplied as explicit parameters (example: Math.pow);

When a method only needs to access static fields of the class (example: Employee.getNextId).

Static fields and methods have the same functionality in Java and C++. However, the syntax is slightly different. In C++, you use the :: operator to access a static field or method outside its scope, such as Math::PI.

The term "static" has a curious history. At first, the keyword static was introduced in C to denote local variables that don't go away when exiting a block. In that context, the term "static" makes sense: the variable stays around and is still there when the block is entered again. Then static got a second meaning in C, to denote global variables and functions that cannot be accessed from other files. The keyword static was simply reused, to avoid introducing a new keyword. Finally, C++ reused the keyword for a third, unrelated interpretation, to denote variables and functions that belong to a class but not to any particular object of the class. That is the same meaning that the keyword has in Java.

Factory Methods

Here is another common use for static methods. Consider the methods

NumberFormat.getNumberInstance()

NumberFormat.getCurrencyInstance()

that we discussed in Chapter 3. Each of these methods returns an object of type NumberFormat. For example,

NumberFormat formatter = NumberFormat.getCurrencyInstance();

System.out.println(formatter.format(salary));

// prints salary with currency symbol

As you now know, these are static methods—you call them on a class, not an object. However, their purpose is to generate an object of the same class. Such a method is called a factory method.

Why don't we use a constructor instead? There are two reasons. You can't give names to constructors. The constructor name is always the same as the class name. In the NumberFormat example, it makes sense to have two separate names for getting number and currency formatter objects. Furthermore, the factory method can return an object of the type NumberFormat, or an object of a subclass that inherits from NumberFormat. (See Chapter 5 for more on inheritance.) A constructor does not have that flexibility.

The main Method

Note that you can call static methods without having any objects. For example, you never construct any objects of the Math class to call Math.pow.

For the same reason, the main method is a static method.

public class Application

{

public static void main(String[] args)

{

// construct objects here

. . .

}

}

The main method does not operate on any objects. In fact, when a program starts, there aren't any objects yet. The static main method executes, and constructs the objects that the program needs.

Every class can have a main method. That is a handy trick for unit testing of classes. For example, you can add a main method to the Employee class:

class Employee

{

public Employee(String n, double s,

int year, int month, int day)

{

name = n;

salary = s;

GregorianCalendar calendar

= new GregorianCalendar(year, month - 1, day);

hireDay = calendar.getTime();

}

. . .

public static void main(String[] args) // unit test

{

Employee e = new Employee("Romeo", 50000);

e.raiseSalary(10);

System.out.println(e.getName() + " " + e.getSalary());

}

. . .

}

If you want to test the Employee class in isolation, you simply execute

java Employee

If the employee class is a part of a larger application, then you start the application with

java Application

and the main method of the Employee class is never executed.

The program in Example 4-3 contains a simple version of the Employee class with a static field nextId and a static method getNextId. We fill an array with three Employee objects and then print the employee information. Finally, we print the number of identification numbers assigned.

Note that the Employee class also has a static main method for unit testing. Try running both

java Employee

and

java StaticTest

to execute both main methods.

Example 4-3 StaticTest.java

1. public class StaticTest

2. {

3. public static void main(String[] args)

4. {

5. // fill the staff array with three Employee objects

6. Employee[] staff = new Employee[3];

7.

8. staff[0] = new Employee("Tom", 40000);

9. staff[1] = new Employee("Dick", 60000);

10. staff[2] = new Employee("Harry", 65000);

11.

12. // print out information about all Employee objects

13. for (int i = 0; i < staff.length; i++)

14. {

15. Employee e = staff[i];

16. e.setId();

17. System.out.println("name=" + e.getName()

18. + ",id=" + e.getId()

19. + ",salary=" + e.getSalary());

20. }

21.

22. int n = Employee.getNextId(); // calls static method

23. System.out.println("Next available id=" + n);

24. }

25. }

26.

27. class Employee

28. {

29. public Employee(String n, double s)

30. {

31. name = n;

32. salary = s;

33. id = 0;

34. }

35.

36. public String getName()

37. {

38. return name;

39. }

40.

41. public double getSalary()

42. {

43. return salary;

44. }

45.

46. public int getId()

47. {

48. return id;

49. }

50.

51. public void setId()

52. {

53. id = nextId; // set id to next available id

54. nextId++;

55. }

56.

57. public static int getNextId()

58. {

59. return nextId; // returns static field

60. }

61.

62. public static void main(String[] args) // unit test

63. {

64. Employee e = new Employee("Harry", 50000);

65. System.out.println(e.getName() + " " + e.getSalary());

66. }

67.

68. private String name;

69. private double salary;

70. private int id;

71. private static int nextId = 1;

72. }

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有