static(静态)关键字

用Ststic后产生的效果分析图

  静态变量代表方法共有的变量【JAVA中没有全局变量的概念】

静态特点【例二】

  ①随着类的加载而加载,随着类的消失而消失

    也就是说,静态会随着类的消失而消失,说明他的生命周期最长

  注意:当类一旦被加载时,static定义的静态变量就存在

  ②优先于对象存在

  明确一点:静态变量是先存在的,对象是后存在的

  ③被所有对象共享  

  ④可以直接被类名所调用

  ⑤只要一个实例把它改变,所有实例都会改变

静态变量【类变量】和普通变量【实例变量】的区别

  随着类的加载而加载,存在于方法区

  实例变量随着对象的建立存在于堆内存中,实例成员与特定的对象关联

生命周期

  类变量生命周期最长,随着类的消失而消失

  实例变量随着对象的消失而消失

图像分析

用法

  是一个修饰符,用于修饰(成员变量,成员函数)

  当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用

  调用方式:类名.静态成员【例一】

例一

 1 public class Exam {
 2     public static void main(String[] args) {
 3         Person person = new Person();
 4         // person.show();
 5         System.out.println(Person.country); //CN
 6     }
 7 }
 8 
 9 class Person {
10     static String country = "CN";
11 
12     void show() {
13         System.out.println(country);
14     }
15 
16 }

例二

 1 public class Exam {
 2     public static void main(String[] args) {
 3         Person person = new Person();
 4         // person.show();
 5         System.out.println(Person.country); // CN
 6     }
 7 }
 8 
 9 class Person {
10     String name; // 成员变量,实例变量
11     static String country = "CN"; // 静态成员变量,类变量
12 
13     void show() {
14         System.out.println(name + ":" + country);
15     }
16 
17 }

静态变量使用注意事项

  静态方法只能访问静态成员【方法和变量】 

        非静态方法可以访问非静态变量,也可以访问静态变量【因为根据先来后到,有方法时已经有了静态变量,所以可以调用】

    函数加上static就是说明这个函数是静态的,如果要使用这个函数不需要先new出这个对象,可以直接使用类名.方法名

示例代码

代码一

 1 public class Exam {
 2     public static void main(String[] args) {
 3 
 4         Person.show(); //CN
 5     }
 6 }
 7 
 8 class Person {
 9     String name; // 成员变量,实例变量
10     static String country = "CN"; // 静态成员变量,类变量
11 
12     public static void show() {
13         System.out.println(country);
14     }
15 
16 }

代码二

 1 public class Exam {
 2     public static void main(String[] args) {
 3 
 4         Person.show(); //CN
 5     }
 6 }
 7 
 8 class Person {
 9     String name; // 成员变量,实例变量
10     static String country = "CN"; // 静态成员变量,类变量
11 
12     public static void show() {
13         System.out.println(name);
14     }
15 
16 }

编译错误提示

原因:因为连对象都没创建,name也不存在,根据先来后到顺序,static已经存在时对象还不存在,所以静态方法不能调用实例变量

  ②静态方法中不可以定义this,super关键字,因为静态优先于对象存在,不可以出现this

静态方法利弊

利:对对象共享数据进行单独空间的存储,节省空间,没有必要每个对象中都存一份

  可以直接被类名调用

换一种解释

  对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。

弊端:生命周期过长,访问出现局限性(静态虽好,只能访问静态)         

  ③主函数是静态的 

换一种解释

  对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)

注意:静态方法是类内部的一类特殊方法,只有在需要时才将对应的方法声明成静态的,一个类内部的方法一般都是非静态的

所以一般在需要实现以下两个功能时使用静态变量:

  • 在对象之间共享值时
  • 方便访问变量时

什么时候使用静态

 要从以下两方面入手: 

    因为静态修饰的内容有成员变量和函数

   什么时候定义静态变量(类变量)?

    当对象中出现共享数据时,该数据被静态所修饰,这里的共享数据指的不只是属性相同,内容也要相同

    如【某某学校的学生的共享属性就是:他们是某某学校的学生,而像性别,姓名,年龄这些都不是】

    对象中的特有数据要定义为非静态存在于堆内存中

  什么时候定义静态函数?

    当功能内部没有访问到非静态数据(对象的特有数据)

    那么该功能可以定义为静态【例三】

例三

代码一【可以定义静态,功能中没有涉及到非静态变量】

 1 public class Exam {
 2     public static void main(String[] args) {
 3         Dog dog = new Dog();
 4         dog.test();  //我是静态方法
 5     }
 6 }
 7 
 8 class Dog {
 9     String name = "ABC";
10 
11     public static void test() {
12         System.out.println("我是静态方法");
13     }
14 }

代码二【不可以定义静态,功能中涉及到非静态变量】

 1 public class Exam {
 2     public static void main(String[] args) {
 3         Dog dog = new Dog();
 4         dog.test();  //我是静态方法ABC
 5     }
 6 }
 7 
 8 class Dog {
 9     String name = "ABC";
10 
11     public void test() {
12         System.out.println("我是静态方法"+name);
13     }
14 }

静态的应用【待看】

  每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用

静态代码块

书写规则  

1 static
2     {
3         静态代码块中的执行语句
4     }

特点

  随着类的加载而执行,只执行一次,用于给类进行初始化,并优先于主函数先执行

 1 public class Exam {
 2 
 3     static {
 4         System.out.println("A");
 5     }
 6 
 7     public static void main(String[] args) {
 8         new Demo();
 9         new Demo();
10         System.out.println("over");
11     }
12 
13     static {
14         System.out.println("B");
15     }
16 }
17 
18 class Demo {
19     static {
20         System.out.println("C");
21     }
22 }

执行结果

之所以C只出现了一次是因为static方法随着类的加载而执行,只执行了一次

注意:容易考察执行顺序

  静态代码块>构造代码块>构造方法>普通方法

例题

 1 public class Exam {
 2 
 3     Exam() {
 4         System.out.println("A");
 5     }
 6 
 7     Exam(int a) {
 8         System.out.println("B");
 9     }
10 
11     {
12         System.out.println("C");
13     }
14 
15     static {
16         System.out.println("D");
17     }
18 
19     public static void main(String[] args) {
20         new Exam(5);
21 
22     }
23 
24 }

执行结果

对象初始化过程

代码  

 1 public class Exam {
 2 
 3     public static void main(String[] args) {
 4         Test test = new Test("张三", 10);
 5     }
 6 }
 7 
 8 class Test {
 9     private String name;
10     private int a;
11 
12     Test(String name, int a) {
13         this.name = name;
14         this.a = a;
15         System.out.println(name + "," + a);
16     }
17 
18     {
19         System.out.println("A");
20     }
21 
22     static {
23         System.out.println("B");
24     }
25 
26     public static void Test1() {
27         System.out.println("C");
28     }
29 
30 }

运行结果

代码解析

Test test = new Test("张三",10)

这句话做了什么事情?

1.因为new用到了Test.class,所以会找到Test.class文件加载到内存中

2.执行该类中的static代码块,如果有的话,给Test.class类进行初始化

3.在堆内存中开辟空间,分配内存地址

4.在堆内存中建立对象的特有属性,并进行默认初始化

5.对属性进行显示初始化

6.对对象进行构造代码块初始化

7.对对象进行与之对应的构造函数初始化

8.将内存地址付给栈内存中的test变量

 图像分析

 1 public class Exam {
 2 
 3     public static void main(String[] args) {
 4         Test test = new Test("张三", 10);
 5         test.Test2("李四");
 6         test.Test1();
 7     }
 8 }
 9 
10 class Test {
11     private static String country = "BJ";
12     private String name;
13     private int a;
14 
15     Test(String name, int a) {
16         this.name = name;
17         this.a = a;
18         System.out.println(name + "," + a);
19     }
20 
21     {
22         System.out.println("A");
23     }
24 
25     public void Test2(String name) {
26         this.name = name;
27     }
28 
29     static {
30         System.out.println("B");
31     }
32 
33     public static void Test1() {
34         System.out.println(country);
35     }
36 
37 }

运行结果

图像分析

 

posted @ 2016-08-07 14:21  IT蓄水池  阅读(224)  评论(0)    收藏  举报