Java 7之基础 - static关键字

来源:互联网 发布:新买的域名怎么备案 编辑:程序博客网 时间:2024/04/28 18:26

被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

其实就相当于JavaScript的全局变量,只是Java无法将其放到类的外部,所以就使用static关键字来标识。


1、static修饰方法: 


当static关键字修饰方法时,这个方法就称为静态方法。静态方法属于类而不属于实例对象。那么静态方法如何进行调用?可以通过类名.方法名来直接调用,也可以通过实例对象.方法名来调用。

使用static关键字修饰的方法在类加载的时候就会加载到内存中。是被指向所属的类而不是实例。Java应用程序的主方法不可以省略static关键字,这是由于如果一个类她定义了main方法的话,那么她的main方法会在这个类的构造函数运行之前被调用。由于main方法运行的时候尚未在JVM里生成相应对象(构造函数未被执行),所以要声明为static。

下面来看一个例子:

public class Something {     public static void main(String[] args) {        Something s = new Something();        System.out.println("s.doSomething() returns " + doSomething());        // System.out.println("s.doSomething() returns " + s.doSomething());//正确写法     }    public String doSomething() {        return "Do something ...";    }}

错.main是static的。静态方法不能直接调用非静态方法。这是由于,静态方法可以直接调用,而非静态方法属于实例对象,而如果此时在静态的主方法中调用并未加载到内存的非静态方法,则必然出错。

同理,静态方法也不能访问非静态变量。

静态方法也是方法,那么静态方法是否也有一般的一些特性呢?比如是否可以被覆盖。来看一下下面的例子。

class Person {static String name, department;public  void printValue() {System.out.println("name is " + name);System.out.println("department is " + department);}}public class Test02 extends Person {static int salary;public  void printValue() {System.out.println("salary is " + salary);}public static void main(String args[]) {Person t1 = new Test02();t1.printValue();//子类的方法覆盖了父类的方法Test02 t2 = new Test02();t2.printValue();// 子类继承了父类的方法}}
运行的结果为:
salary is 0

salary is 0

class Person {static String name, department;public  static void printValue() {System.out.println("name is " + name);System.out.println("department is " + department);}}public class Test02 extends Person {static int salary;public  static void printValue() {System.out.println("salary is " + salary);}public static void main(String args[]) {Person t1 = new Test02();t1.printValue();Test02 t2 = new Test02();t2.printValue();}}
运行结果为:

name is null
department is null
salary is 0

可以看出,这并不是覆盖,其实静态方法只可以被隐藏,而不可以覆盖。当t1为Person类型时,则调用Person类的静态方法,因为静态方法只属于这个类,而当t2类型为Test02时,调用子类的静态方法,当子类没有时,调用父类的方法,这就叫做继承父类的方法了。

例如删除test02类中的printValue()方法,则运行结果如下:

name is null
department is null
name is null
department is null



2、static修改属性:


当static修饰属性时,与类一样,都是在类加载时就加载到了内存。通常static修改变量在项目开发中有着重要的应用。由于他只会在内存中保存一份,所以可以节省空间资源。而常见的单例模式就是其重要的应用。

//饿汉式public class Singleton {private static Singleton singleton = new Singleton(); // 在类加载时进行初始化private Singleton(){}public static Singleton getInstance(){return singleton;}}//懒汉式public class Singleton {private static Singleton singleton;                  // 静态私有变量private Singleton(){}                                // 私有构造函数public static synchronized Singleton getInstance(){  // 同步方法if(singleton==null){singleton = new Singleton();         // 在调用的时候初始化}return singleton;}}

可以看到,通过如上代码,就可以保持一个singleton实例的引用,防止出现多个实例对象而浪费资源。同时还可以进行全局的访问。


3、static修饰块:  


加static修饰的块也会随着类的加载而进入内存,所以可以在这里初始化一些静态成员变量。


4、static修饰类(静态内部类:

public class TestStaticClass {          public TestStaticClass(){     System.out.println("TestStaticClass class invoked!");     }     static class innerStatic{     innerStatic(){     System.out.println("innerStatic class invoked!");     }     }}
public class JunitTest {@Test    public void testInnerStaticClass(){/** * 说明两个类是完全独立的 */new TestStaticClass();  // 并不会初始化静态内部类 innerStatic class invoked!    new TestStaticClass.innerStatic(); // 并不会初始化外部类 innerStatic class invoked!    }}

5、使用static注意事项总结:


  1.  当类被虚拟机加载时,按照声明顺序先后初始化static成员字段和static语句块
  2.  static所修饰的方法和变量只属于类,所有对象共享。
  3.  在static所修饰的方法和语句块中不能使用非static成员字段。
  4.   静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已,把“全局变量”放在内部类中就是毫无意义的事情,所以  被禁止
  5.  在Java不能直接定义全局变量,是通过static来实现的
  6.  在Java中没有const,不能直接定义常量,通过static final来实现






















原创粉丝点击