static的主要作用有:
Java静态属性和类相关,和具体的实例无关,换句话说,同一个类的不同实例共用一个静态属性。
例如:
class Demo{
public int a;
public static int count;
}
public static void main(String[] args) {
Demo demo=new Demo();
demo.a++;
Demo.count++;
System.out.println(demo.a);
System.out.println(Demo.count);
System.out.println("+++++++++++++++++");
Demo demo2=new Demo();
demo.a++;
Demo.count++;
System.out.println(demo.a);
System.out.println(Demo.count);
}
结果是:
1
1
+++++++++++++
1
2
因为count被static修饰,所有的类共享,且不属于对象,访问使用的时候,直接用类名.count。
这是因为在被static修饰后,在jvm中被放在了方法区中,而只有一份,所以可以共享。
在任何方法上,使用static关键字,这个方法就被称为静态方法
例如:
public class Demo2 {
public int a;
public static int count;
public static void method() {
count = 100;
// a = 10; //不能使用非静态的属性
}
}
public class Test {
public static void main(String[] args) {
Demo2.method();
System.out.println(Demo2.count);
}
}
结果是:
这上面代码,我们可以看出a不可以在method中被调用。而静态的方法可以通过类名直接调用,不需要创建实例化对象。
注意:
静态方法和实例无关,而和类相关,所以:
1、静态方法不能直接使用非静态数据成员或调用方法(非静态数据成员和方法都是实例相关的)
2、this和super两个关键字不能在静态上下文中使用(this指向当前对象,super是当前实例父类实例的引用)
3、main方法是static的
1、定义时初始化,
2、静态代码块初始化
例如:
public static int = 10;//定义时初始化
static{
System.out.println("静态代码块");
}
在使用的时候,我们使用的时候,那些会用static,那些不用?
最基本的方法:
如果方法执行的时候,需要用到this,就必须不加static
否则,在方法执行的过程中,不会用到this,可以加static,也可以不加
什么是类的加载?
jvm在程序执行的时候,需要用到类中的信息,但jvm只能读取内存的数据,所以需要进一步操作,把类中的信息,从硬盘上.class文件读取出来放在合适的位置。
类一旦被加载过一次,则在整个程序的运行期间,不需要被再次加载。在程序运行期间,用到的类,只会加载1次
jvm在实现类的加载,并不是一开始就把所有用到的类全部加载进来,而是真正使用的时候才加载。
当一个类首次被使用,对该类加载,加载的同时,执行类的初始化过程。
例如:
class 执行顺序 {
public static int a = initStatic();
{
System.out.println("A");
}
public 执行顺序() {
this("Hello");
System.out.println("B");
}
public 执行顺序(String s) {
System.out.println("C");
}
public int b = init();
public static int initStatic() {
System.out.println("D");
return 0;
}
public int init() {
System.out.println("E");
return 0;
}
static {
System.out.println("F");
}
}
public class 看看打印是什么 {
public static void main(String[] args) {
System.out.println("1");
new 执行顺序();
System.out.println("2");
new 执行顺序();
System.out.println("3");
}
}
观察上面代码,当类加载后,运行后结果是什么?
首先进入main方法,输出一个1,进入类中,执行静态代码初始化:
public static int a = initStatic();
static {
System.out.println("F");
}
两个是同一级别,谁在前面谁先执行,所以先a,然后调用 initStatic()方法,输出D,然后输出F。静态初始化完成后,进行实例化初始化,然后new一个新对象,首先执行定义初始化,构造代码初始化,按照书写顺序执行。AE。然后执行构造方法,书写顺序执行,CB
第二次因为静态初始化,只执行一次,所以结果是AECB。
在类的加载中,静态初始化只初始化一次,且在类首次用到时,按照静态属性定义初始化,静态代码块初始化,按照书写顺序执行。
而实例对象初始化(非静态时候),第一类:定义时初始化,构造代码块初始化, 按照书写顺序
第二类:构造方法 ,
无论书写顺序,首先执行第一类,然后第二类。