Java static关键字

static关键字主要和Java的内存管理有关。我们可以将static关键字与变量,方法,代码块一起使用。static关键字属于该类,而不是该类的实例。

static关键字可以修饰:

  1. 变量(也称为类变量)
  2. 方法(也称为类方法)
  3. 代码块

1 Java静态变量

如果将任何变量声明为static,则称为静态变量。

  • 静态变量可用于引用所有对象的公共属性(每个对象不是唯一的),例如,员工的公司名称,学生的大学名称等。
  • 静态变量在类加载时仅在类区域中分配一次内存。

1.1 静态变量的优点

它使你的程序存储效率更高(通俗点说,就是节省内存)。

1.2 没有使用静态变量的弊端

class Student{  
     int rollno;  
     String name;  
     String college="中国人民大学";  
}  

假设我的大学里有500名学生,那么现在每次创建对象时,所有实例数据成员都将分配内存。所有学生都应用拥有唯一的rollno和name,因此rollno和name作为实例成员是OK的。但是,“colleage”是所有学生对象的共同属性。如果我们将其设为static,则该字段将仅分配一次内存,这样就节省内存空间啦!

注意:Java静态属性是共享给所有对象的。

1.3 静态变量示例

/**
 * 一点教程网 - http://www.yiidian.com
 */
//使用静态变量示例
class Student{
    int rollno;//实例变量
    String name;
    static String college ="中国人民大学";//静态变量
    //构造方法
    Student(int r, String n){
        rollno = r;
        name = n;
    }
    //打印对象数据
    void display (){
        System.out.println(rollno+" "+name+" "+college);
    }
}

//测试类
public class Demo{
    public static void main(String args[]){
        Student s1 = new Student(111,"张三");
        Student s2 = new Student(222,"李四");
        //我们可以通过下面这行代码改变Student的colleage属性值,发现所有对象的colleage属性值会同时被更改!
        Student.college="上海交通大学";
        s1.display();
        s2.display();
    }
}

输出结果为:

111 张三 上海交通大学
222 李四 上海交通大学

1.4 没有使用静态变量的计数器

在下面示例中,我们创建了一个名为count的实例变量,该变量在构造方法中递增。由于实例变量在创建对象时分配内存,因此每个对象都将具有实例变量的副本。如果count的值增加,将不会影响其他对象。因此,每个对象在count变量中的值为1。

/**
 * 一点教程网 - http://www.yiidian.com
 */
//没有使用静态变量(而是实例变量)的计数器
//每次创建类的对象时,实例变量都会分配内存。
class Counter{
    int count=0;//每个对象创建的时候,count都会分配到内存

    Counter(){
        count++;//递增
        System.out.println(count);
    }

    public static void main(String args[]){
        //创建对象
        Counter c1=new Counter();
        Counter c2=new Counter();
        Counter c3=new Counter();
    }
}

输出结果为:

1
1
1

1.5 使用静态变量的计数器

如上所述,静态变量仅仅分配一次内存,如果任何对象更改了静态变量的值,该值会影响所有对象。

/**
 * 一点教程网 - http://www.yiidian.com
 */
//使用静态变量的计数器 
//静态变量是所有对象共享的  
class Counter2{
    static int count=0;//只在第一个对象创建时分配内存 

    Counter2(){
        count++;//递增
        System.out.println(count);
    }

    public static void main(String args[]){
        //创建对象
        Counter2 c1=new Counter2();
        Counter2 c2=new Counter2();
        Counter2 c3=new Counter2();
    }
}  

输出结果为:

1
2
3

2 Java静态方法

如果让任何方法加上static关键字,则称为static静态方法。

  • 静态方法属于类,而不是类的对象。
  • 可以使用类名称直接调用静态方法,而无需创建类的实例。
  • 静态方法可以直接访问静态数据成员并可以更改其值。

2.1 Java静态方法示例1

/**
 * 一点教程网 - http://www.yiidian.com
 */
//使用静态方法的示例
class Student{
    int rollno;
    String name;
    static String college = "中国人民大学";
    //使用静态方法修改静态变量
    static void change(){
        college = "上海交通大学";
    }
    //带参数的构造方法
    Student(int r, String n){
        rollno = r;
        name = n;
    }
    //打印对象数据
    void display(){System.out.println(rollno+" "+name+" "+college);}
}
//测试类
public class Demo{
    public static void main(String args[]){
        Student.change();//调用静态方法
        //创建对象
        Student s1 = new Student(111,"张三");
        Student s2 = new Student(222,"李四");
        Student s3 = new Student(333,"王五");
        //打印对象数据
        s1.display();
        s2.display();
        s3.display();
    }
}

输出结果为:

111 张三 上海交通大学
222 李四 上海交通大学
333 王五 上海交通大学

2.2 Java静态方法示例2

/**
 * 一点教程网 - http://www.yiidian.com
 */
//使用静态方法进行计算的示例
class Calculate{
    static int cube(int x){
        return x*x*x;
    }

    public static void main(String args[]){
        int result=Calculate.cube(5);
        System.out.println(result);
    }
}

输出结果为:

125

2.3 Java静态方法的限制

静态方法有两个主要限制:

  • 静态方法不能使用非静态数据成员或直接调用非静态方法。
  • this和super关键字不能在静态上下文中使用。
/**
 * 一点教程网 - http://www.yiidian.com
 */
class A{
    int a=40;//non static  

    public static void main(String args[]){
        System.out.println(a);
    }
} 

以上代码会编译报错,因为静态方法调用了非静态成员。

2.4 为什么main方法是静态的

如果main() 方法是非静态方法,则JVM首先创建一个对象,然后调用main() 方法,这将导致额外的内存分配问题。

3 Java静态代码块

3.1 Java静态代码块示例

/**
 * 一点教程网 - http://www.yiidian.com
 */
//静态代码块示例
class A2{
    static{System.out.println("静态代码块被执行...");}
    public static void main(String args[]){
        System.out.println("你好,一点教程网的小伙伴");
    }
}

输出结果为:

静态代码块被执行...
你好,一点教程网的小伙伴

3.2 可以执行没有main()方法的类吗

JDK1.6以前可以,但是JDK1.7以后不行!JDK1.6及以前只要类中有静态块也可以执行该类,但是到了JDK 1.7及以后,没有main方法就不可能执行Java类了。

推荐好课