浅谈java中的static关键字

学习自:http://www.cnblogs.com/dolphin0520/p/3799052.html

static关键字主要有两种作用:

第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。比如一些常量

第二,实现某个方法或属性与类而不是对象关联在一起

具体而言,在Java语言中,static主要有4中使用情况:成员变量、成员方法、代码块和内部类

举例:下面的单例模式方法中为什么要用static修饰符来修饰getInstance方法。可以在不用创建对象Singlteon的时候直接通过

 Singleton1.getInstance();实现此方法。

package Singleton;

/**
 * Created by hanzhixiong on 2017/10/9.
 */
public class Singleton1 {
    private static Singleton1 instance;
    //private Singleton1(){};//构造类
   
public static Singleton1 getInstance(){
        if(null ==instance){
            instance = new Singleton1();
        }
        return instance;
    }

}

importSingleton.Singleton1;

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        Singleton1.getInstance();
    }
}

一、什么是java关键字

   在《Java编程思想》P86页有这样一段话:

“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:

方便在没有创建对象的情况下来进行调用(方法/变量)。

很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。

static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。

1)static方法

  static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

  但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的举例

因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

另外记住,即使没有显示地声明为static,类的构造器实际上也是静态方法。

 

2)static变量

  static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

但是要注意:Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字

static成员变量的初始化顺序按照定义的顺序进行初始化。

二.static关键字的误区

1.static关键字会改变类中成员的访问权限吗?

  有些初学的朋友会将java中的static与C/C++中的static关键字的功能混淆了。在这里只需要记住一点:与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了:

  提示错误"Person.age 不可视",这说明static关键字并不会改变变量和方法的访问权限。

2.能通过this访问静态成员变量吗?

  虽然对于静态方法来说没有this,那么在非静态方法中能够通过this访问静态成员变量吗?先看下面的一个例子,这段代码输出的结果是什么?

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {  
    static int value = 33;
 
    public static void main(String[] args) throws Exception{
        new Main().printValue();
    }
 
    private void printValue(){
        int value = 3;
        System.out.println(this.value);
    }
}

 

 View Code

  这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。

3.static能作用于局部变量么?

  在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。

注意static和final的区别和联合使用

final可以修饰:属性,方法,类,局部变量(方法中的变量)

     final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变。

     final修饰的属性跟具体对象有关,在运行期初始化的final属性,不同对象可以有不同的值。

     final修饰的属性表明是一个常数(创建后不能被修改)。

     final修饰的方法表示该方法在子类中不能被重写,final修饰的类表示该类不能被继承。

     对于基本类型数据,final会将值变为一个常数(创建后不能被修改);但是对于对象句柄(亦可称作引用或者指针),final会将句柄变为一个常数(进行声明时,必须将句柄初始化到一个具体的对象。而且不能再将句柄指向另一个对象。但是,对象的本身是可以修改的。这一限制也适用于数组,数组也属于对象,数组本身也是可以修改的。方法参数中的final句柄,意味着在该方法内部,我们不能改变参数句柄指向的实际东西,也就是说在方法内部不能给形参句柄再另外赋值)。

 

 

static可以修饰:属性,方法,代码段,内部类(静态内部类或嵌套内部类)

     static修饰的属性的初始化在编译期(类加载的时候),初始化后能改变。

     static修饰的属性所有对象都只有一个值。

     static修饰的属性强调它们只有一个。

     static修饰的属性、方法、代码段跟该类的具体对象无关,不创建对象也能调用static修饰的属性、方法等

     static和“this、super”势不两立,static跟具体对象无关,而this、super正好跟具体对象有关。

     static不可以修饰局部变量。

 

static final和final static没什么区别,一般static写在前面。

static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。

static final也可以修饰方法,表示该方法不能重写,可以在不new对象的情况下调用。

 

posted @ 2017-10-09 09:19  熊窝窝  阅读(733)  评论(0编辑  收藏  举报