目录
一.static 关键字是什么。
static 修饰的代码属于类(存放在静态常量池当中),没有static修饰的代码要在堆空间中创建对象来使用。
测试类
public class Test{ public static void main(String[] args){ A a = new A(); a.fun(); a.flay(); A.name = "aaa"; A.run(); A.flay(); } }
二.java为什么设计static关键字?
因为要方便类去使用自己的方法和变量
(1)如果没有static修饰的时候
方法和变量的信息存储在方法区中,他们只有在对象当中才会被分配到内存空间,因此只有对象才能调用。
A类和Test类这些代码信息都存储在方法区中。
public class A{ public String name = "admin"; public void run(){ System.out.println("跑的还不快"); } public void flay(){ System.out.println("飞的很高"); } }
(2)如果有static修饰的时候
方法和变量存在静态常量池中,可以由类直接调用(但也可以有对象调用,会有模糊处理)。
public class A{ public static String name = "admin"; public static void run(){ System.out.println("跑的还不快"); } public static void flay(){ System.out.println("飞的很高"); } }
从上一张图可以看出,没有static关键字,类不可以调用自己的变量和方法。(在方法区中类信息只是存储不能直接到内存中调用,但在静态常量池变量和方法可以)
三.static 关键字怎么用。
static
修饰变量:
static修饰的变量属于类变量,存储在方法区的静态常量池当中,被所有对象共享。
修饰方法:
(1)static修饰的方法无法调用到非静态方法。(非静态方法没有加强再到内存中)
(2)在非静态方法当中可以调用到静态方法。(静态方法在静态常量池当中)
public class A{ public static void a(){ b(); } public void b(){ } }
public class A{ public static void a(){ } public void b(){ a(); } }
第一个不行,第二个可以。
*如果一个方法像被main方法调用
(1)在非静态方法上加入static关键字
(2)在main方法中创建对象,让对象调用该静态方法
修饰代码块:
在main方法运行之前运行,目的是优化程序。
例题1:
public class Base extends Bas{ static{ System.out.println("base static"); } public Base(){ System.out.println("base constructor"); } public static void main(String[] args) { new Base(); } } class Bas{ static { System.out.println("bas static"); } public Bas(){ System.out.println("bas constructor"); } }
首先,对Test类进行扫描(其中有main方法),发现其有父类Base,扫描Base(直到没有父类为止),接着编译为Base.class放入方法区执行static代码块 base static(static代码块优先main执行),然后编译Test.class,放入方法区,执行static代码块 test static。
接着,main方法入栈,创建Test对象(子类对象,先创建父类Base对象),则先执行Base构造器里的内容 base constructor 而后是Test的内容 test constructor。
例题2:
public class Test { public Test(String aa){ System.out.println("===="+aa); } static { System.out.println("11"); } public static Test test = new Test("+++"); static{ System.out.println("22"); } } class Demo{ public static void main(String[] args) { Test test = new Test("----"); } }
1.扫描Demo类,发现其没有父类,main方法入栈。
2.执行new Test();扫描Test类,执行第一个static代码块,输出11
3.public static Test test = new Test("+++");根据Test()构造器输出====+++
4.执行第二个static代码块,输出22
5.执行main方法输出====----
例题3:
public class A { private static int a; public static void main(String[] args) { m(a); System.out.println(a); } public static int m(int a){ return a++; } }
输出是0,方法内的变量是局部变量,不能影响静态常量池当中的a。