[2014-02-27]JAVA笔记_Static关键字、代码块{}、main()、final关键字

来源:互联网 发布:淘宝描述排版器 编辑:程序博客网 时间:2024/06/06 17:00

Static关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类。

Static修饰属性:无论一个类生产多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们通过类名.成员变量名的方式来使用它(推荐使用这种方式)。

public class StaticTest{public static void main(String args[]){/*MyStatic myStatic = new MyStatic();MyStatic myStatic2 = new MyStatic();myStatic.a = 10;System.out.println(myStatic2.a);*///使用类名访问成员变量MyStatic.a = 10;System.out.println(MyStatic.a);}}class MyStatic{static int a;}

在程序中使用static声明属性,则此属性称为全局属性(或成为静态属性).

例1:使用static声明属性

class Person{String name;int age;static String country = "A城";//使用static申明类属性public Person(String name, int age){this.name = name;this.age = age;}public void info(){System.out.println("姓名:" + this.name + " 年龄:"+ this.age + " 城市:" + this.country);}};public class StaticDemo02{public static void main(String args[]){Person p1 = new Person("张三", 30);Person p2 = new Person("李四", 30);Person p3 = new Person("王五", 30);System.out.println("------------修改之前---------");p1.info();p2.info();p3.info();System.out.println("------------修改之前---------");Person.country = "B城";//直接修改static属性p1.info();p2.info();p3.info();fun();}public static void fun(){System.out.println("静态方法无法调用非静态方法,必须有static关键字");};}



static修饰方法:static 修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名 的方式来访问。

public class StaticTest2{public static void main(String args[]){//MyStatic2 test = new MyStatic2();//test.output();MyStatic2.output();}}class MyStatic2{public static void output(){System.out.println("output");}}


·静态方法只能继承,不能重写(override)。
//静态方法的继承public class StaticTest3{public static void main(String args[]){M m = new N();//结果取决于调用着的类型//M m = new M();m.output();}}class M{public static void output(){System.out.println("M");}}class N extends M{public static void output(){System.out.println("N");}}//N类中的方法继承了M中的方法。并隐藏了M中的方法
参考文献:http://docs.oracle.com/javase/tutorial/java/IandI/override.html


例2:使用static声明方法。使用static声明的方法有时也成为类方法

class Person{private String name;private int age;static String country = "A城";//使用static申明类属性public Person(String name, int age){this.name = name;this.age = age;}public void info(){System.out.println("姓名:" + this.name + " 年龄:"+ this.age + " 城市:" + this.country);}public static void setCountry(String c){//使用static申明方法country = c;//修改static属性}public static String getCountry(){return country;}};public class StaticDemo03{public static void main(String args[]){Person p1 = new Person("张三", 30);Person p2 = new Person("李四", 30);Person p3 = new Person("王五", 30);System.out.println("------------修改之前---------");p1.info();p2.info();p3.info();System.out.println("------------修改之前---------");Person.setCountry("B城");//因为是使用static声明的方法,所以也可称为类方法p1.info();p2.info();p3.info();}}

总结: 

        1. static声明的方法是不能调用非static类型声明的属性或方法(因为static得方法在装载class得时候首先完成,比 构造方法早,此时非static得属性和方法还没有完成初始化。。。所以不能调用)。但是非static声明的方法可以去调用static调用的属性或方法。

        2. 使用 static 声明的属性或方法可以直接由类名称调用。

        3. 只能访问 static 声明的属性或方法,而非 static 声明的属性和方法是不能访问,因为 static 可以在对象没有实例化时就直接调用,而其他的属性或方法必须在对象实例化之后才可以调用。


final关键字:final可以修饰 类、 方法、属性。

final修饰类:当一个类被 final 所修饰时,表示该类是一个终态类,即不能被继承。

public class FinalTest{public static void main(String args[]){}}final class E{//该类不能被继承}class F extends E{}

final修饰方法:当一个方法被 final 所修饰时,表示改方法时一个终态方法,即不能被重写(override)。

public class FinalTest2{public static void main(String args[]){H h = new H();h.output();}}class G{public final void output(){System.out.println("G");}}class H extends G{public  void output(){System.out.println("H");}}

final 修饰属性:当一个属性被final 所修饰时,表示该属性不能被改写。

public class FinalTest3{public static void main(String args[]){People people = new People();people.age = 20;}}class People{final int age = 10;}

//使用final修饰地址:public class FinalTest3{public static void main(String args[]){People people = new People();//people.address = new Address();//Error,将新的地址赋值给address引用people.address.name = "shanghai";//修改的是address所指向的地址的内容}}class People{final Address address = new Address();//将引用类型声明为final,意思是new出来的地址是不能改变的}class Address{String name = "bejing";}
总结:当final 修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化(比如说不能从8变为20);如果final修饰的是一个引用数据类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。

//final 陷阱public class FinalTest4{final int a;//必须显示的给变量赋值,否则报错。或者通过构造方法赋初值public FinalTest4(){a = 0;}public FinalTest4(int a){//Error,因为有2个构造方法,调用时不知道会先调用哪个构造方法//this.a = a;<span style="white-space:pre"></span>//或者这样也可以}}

final陷阱:对于final 类型成员变量,一般来说有两种赋初值方式:

                           a) 在声明 final 类型成员变量时就赋上初值
                           b) 在声明 final 类型成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值


·static 代码块: 静态代码块。静态代码块的作用也是完成一些初始化的工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类生成对象,首先需要将类加载到 java 虚拟机上(JVM),然后由JVM 加载这个类生产对象。

//静态代码块public class StaticTest4{public static void main(String args[]){/*P p = new P();P p2 = new P();//static只执行一次,因为class只需要加载一次到JVM,然后每次new的时候执行构造方法。*/new S();//因为静态代码块在加载到JVM的时候就执行了,所以先执行3个static方法,然后在依次查找子类上面的父类构造方法,从父类到一类依次执行。new S();}}class P{static{System.out.println("P static block");//当将class文件加载到JVM时执行}public P(){System.out.println("P constructor");//当 new 这个类生产对象的时候执行}}class Q extends P{static{System.out.println("Q static block");}public Q(){System.out.println("Q constructor");}}class S extends Q{static{System.out.println("S static block");}public S(){System.out.println("S constructor");}}
 ·类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以 new 一次就会调用构造方法一次。
 ·如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层的静态代码块,然后在去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行一次。

//静态方法调用public class StaticTest5{public static void main(String args[]){W w = new W();w.change();}}class W{static int a = 10;int a = 10;//不能在一个静态方法里面访问一个非静态的成员变量public static void change(){//public void change(){//可以因为a的值只有一份是全局的a++;
                this.a++;<span style="white-space:pre"></span>//Error:this表示当前对象的引用。如果直接使用类名调用静态方法的时候,就不存在对象,也就不知道this是什么了}}//因为每次new一个对象的时候都会有自己的一份a的值,所以在静态方法不知道是修改了哪个a的值。
·不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量。
总结:静态的只能访问静态的;非静态的可以访问一切。

·不能在静态方法中使用 this 关键字。


java中的内存区域:

· 栈内存:可以保存对象的名称

· 堆内存:保存每个对象的具体属性

· 全局数据区:保存 static 类型的属性

· 全局代码区:保存所有方法的定义



main方法:

· public: 表示此方法可以被外部所调用

· static: 表示此方法可以由类名直接调用(执行一个java程序的时候,使用的是 java 类名称)

· void: 主方法是程序的起点,所以不需要任何的返回值

· mian: 系统规定好的默认调用的方法名称,执行的时候,默认找到main方法名称

· String args[]: 表示的是运行时的参数

· 参数传递的形式: java 类名称 参数1 参数2 参数3...


代码块:

概念:代码块是指用{}括起来的一段代码,根据位置不同可以分为  普通代码块、构造快、静态代码块、同步代码块  4种。


class Demo{{//定义构造快System.out.println("1、构造块。");}static{//定义静态代码块System.out.println("0、静态代码块。");}{//定义构造方法System.out.println("2、构造方法。");}}public class CodeDemo03{static{//在主方法所在的类中定义静态块System.out.println("在主方法所在的类中定义静态块");}public static void main(String args[]){new Demo();new Demo();new Demo();}}//执行顺序:静态代码块优先于主方法执行,而在类中定义的静态代//码块会优先于构造块执行,而且静态代码块只执行一次。



0 0