Java基础-学习笔记(九)——static关键字
1、静态成员变量
程序中的类,只是在描述其对象的属性和成员,并没有产生实际对象,只有通过new关键字才能产生出对象,这时系统才会分配内存空间给对象,其方法才能供外部调用。
每生成一个对象,都会在内存中给它分配一个单独的空间,有时候我们希望无论产生多少对象,某些某些特定的数据在内存空间里只有一份,我们只需要在这种数据面前加上statice关键字即可。静态变量在某种程度下与其他语言中的全局变量比较类似。并且,我们可以不需要产生实例对象,直接使用类名来调用,如下代码所示
1 class Chinese 2 { 3 static String country="中国"; 4 String name; 5 int age; 6 void SingOurCountry() 7 { 8 System.out.println("啊!,亲爱的"+country); 9 } 10 11 } 12 class TestChinese 13 { 14 public static void main(String [] args) 15 { 16 System.out.println("China is "+Chinese.country); 17 Chinese ch=new Chinese(); 18 ch.SingOurCountry(); 19 } 20 } 21 /* 22 China is 中国 23 啊!,亲爱的中国*/
2、静态方法
有时候不希望创建对象来调用方法,也就是说不想让方法与对象绑定在一起,要达到这样的目的,我们需要在类定义的方法前加上static关键字,可将此类方法称为静态成员方法。同静态成员变量一样,它也可以由类直接调用,也可以创建对象来调用。
1 class Chinese 2 { 3 String name; 4 int age=5; 5 static void SingOurCountry() 6 { 7 //System.out.println("my age is "+age); 8 System.out.println("啊,亲爱的祖国!"); 9 } 10 void Sing()//同类中的非静态方法可以调用静态方法 11 { 12 Chinese.SingOurCountry(); 13 } 14 } 15 class TestChinese 16 { 17 public static void main(String [] args) 18 { 19 Chinese.SingOurCountry(); 20 Chinese ch=new Chinese(); 21 ch.SingOurCountry(); 22 ch.Sing(); 23 } 24 } 25 /* 26 27 F:\java_example>java TestChinese 28 啊,亲爱的祖国! 29 啊,亲爱的祖国! 30 啊,亲爱的祖国!*/
注意事项:
1)静态成员方法中不能访问类中其他的非静态变量或非静态成员方法。因为此时都没有创建对象,非静态成员变量和非静态成员方法都没有分配空间,他们是不存在的;
2)静态方法中不能以任何方式引用this和super关键字。同上理,由于没有创建对象,所以也不知道this所指向的对象是哪个;
3)由于main()就是一个静态的方法,所以他不能访问类中的非静态成员,需要新建实例对象之后,才能引用。
3、静态代码块
一个类可以使用不包含在任何方法中的静态代码块(static block),当类被载入时,静态代码块就被执行,且被执行一次,静态代码块常用来进行类属性的初始化。
1 class StaticCode 2 { 3 static int age; 4 static 5 { 6 age=23; 7 System.out.println("StaticCode is loading..."); 8 } 9 } 10 class TestStaticCode 11 { 12 static 13 { 14 System.out.println("TestStaticCode is loading..."); 15 16 } 17 public static void main(String [] args) 18 { 19 System.out.println("begain executing main method..."); 20 new StaticCode(); 21 new StaticCode(); 22 } 23 } 24 /* 25 F:\java_example>java TestStaticCode 26 TestStaticCode is loading... 27 begain executing main method... 28 StaticCode is loading...*/
以上代码,就充分说明了,static block是在加载类的时候运行,且只执行一次。
4、单态设计模式
单态也就是说类只创建一个实例对象
1 class StaticCode 2 { 3 private StaticCode() 4 {}; 5 static StaticCode obj = new StaticCode(); 6 public static StaticCode getObj() 7 { 8 return obj; 9 } 10 } 11 class TestStaticCode 12 { 13 public static void main(String [] args) 14 { 15 StaticCode obj1=StaticCode.getObj(); 16 StaticCode obj2=StaticCode.getObj(); 17 if(obj1==obj2) 18 System.out.println("only one instance~"); 19 } 20 } 21 /* 22 F:\java_example>java TestStaticCode 23 only one instance~*/
首先,我们要限制程序中该类只产生一个对象,我们知道对象是通过构造函数产生的,那我们就从这里入手,限制构造函数,不让外部调用我们的构造函数,那就需要将它用private进行修饰;
再是,我们说了,只能有一个对象,那我们既然不能在外面调用构造函数,那就得在类内部产生一个对象,并提供方法,让外部程序来进行访问;
还有,外部没有对象,怎么能调用我们的方法来获取这唯一的对象实例呢?那我们顺其自然的就想到了,将这个方法变成静态方法,不用外部创建对象就可以使用;
最后,为什么要在创建对象实例时加一个static呢?如果不加的话,我们静态方法中使用的obj,它是非静态成员,无法进行访问使用。