详解JAVA方法的访问修饰符和修饰符(static)
详解JAVA类的静态器(static)和静态方法:
?? 通常,我们创建类时会通过关键字new方式声明一个类的实例对象,即:
ClassA classA = new ClassA();
在通过类的实例对象调用该类的方法。
如果声明一个类的实例对象,但没有创建该对象。即:
ClassA?? classA = null;
实际上是不能得到该类的任何东西的。只有执行了new运算,才会正式产生数据存储空间,并可使用调用该类的所有的方法(除了私有方法)。
但在两种特殊的情形下,上述方法并不够用。一种情形是只想用一个存储区域来保存一个特定的数据——无论要创建多少个对象,甚至根本不创建对象。另一种情形是我们需要一个特殊的方法,它没有与这个类的任何对象关联。也就是说,即使没有创建对象,也需要一个能调用的方法。为满足这两方面的要求,可使用static(静态)关键字。一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起。所以尽管从未创建那个类的一个对象,仍能调用一个static方法,或访问一些static数据。而在这之前,对于非static数据和方法,我们必须创建一个对象,并用那个对象访问数据或方法。这是由于非static数据和方法必须知道它们操作的具体对象。当然,在正式使用前,由于static方法不需要创建任何对象,所以它们不可简单地调用其他那些成员,同时不引用一个已命名的对象,从而直接访问非static成员或方法(因为非static成员和方法必须同一个特定的对象关联到一起)。
??? 有些面向对象的语言使用了“类数据”和“类方法”这两个术语。它们意味着数据和方法只是为作为一个整体的类而存在的,并不是为那个类的任何特定对象。有时,您会在其他一些Java书刊里发现这样的称呼。 ?
? 为了将数据成员或方法设为static,只需在定义前置和这个关键字即可。例如,下述代码能生成一个static数据成员,并对其初始化: ?
? class?? StaticClassA?? { ?
static?? String? str?? =? “我是一个静态变量,在类的实例化时,首先调用我,为我分配物理存储空间,然后才可以调用类的构造方法”; ?
public StaticClassA(){
??????????????? System.out.println(“已经为本类的所有静态变量分配了物理存储空间”);
}
? }? ?
测试案例:
/**
?* 通过不同的调用方式,测试类的静态器和静态方法的加载顺序
?* @author fanjf
?* @date 2012-2-25
?*/
public class StaticMethod {
??????? static{
??????????????? System.out.println("StaticMethod 的静态器");
??????? }
?????? ?
??????? /**
???????? * 当不是通过new创建一个类的实例,直接调用这个类的静态方法是否执行该类的静态器
???????? * @return void
???????? * @author fanjf
???????? * @date 2012-2-25
???????? */
??????? public static void testStaticMethod(){
??????????????? System.out.println("StaticMethod 的静态方法");
??????? }
}
在写一个测试类,测试上述类的静态器和静态方法的加载顺序:
(1)
执行代码:StaticMethod sm = new StaticMethod();
输出语句:
StaticMethod 的静态器
这是最基本的,也是大家很容易理解:实例化类时,自动加载类的静态器。
(2)
执行代码:StaticMethod me = null;
则不输出任何语句。
这是因为:声明一个类的对象,但没有实例化,不加载该类的任何东西。
(3)
执行代码:StaticMethod.testStaticMethod();
输出语句:
StaticMethod 的静态器
StaticMethod 的静态方法
这是为什么呢?这就要谈到:JAVA类的加载,连接与初始化。
Java程序对类的使用方式可分为两种:主动使用和被动使用。
所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们。
主动使用分为六种:
1,创建类的实例;
2,访问某个类或接口的静态变量,或者对该静态变量赋值。
3,调用类的静态方法
4,反射:如Class.forName(“类的全名:com.fanjf.StaticMethod”)
5,初始化一个类的子类(它会首先加载其父类的所有静态成员:静态变量,静态器。不包含静态方法)。
6,Java虚拟机启动时被标明为启动类的类。
除了以上6种情况,其他使用Java类的方式都被看作是对垒的被动使用,都不会导致类的初始化。
如 ClassA classA = null。
所以上述输出是因为主动使用了Java类的第三种:
(4)
如果一起执行如下代码,则输出什么呢?大家不妨动手试试:调用类的静态方法。
StaticMethod me = null;
System.out.println("——————————————");
?????????????? ?
StaticMethod.testStaticMethod();
System.out.println("——————————————");
?????????????? ?
StaticMethod sm = new StaticMethod();