static:
static可以用来修饰:属性、方法、代码块、内部类。
被修饰后的成员具备以下特点:
1、随着类的加载而加载。
2、优先于对象存在。
3、修饰的成员,被所有对象所共享。
4、访问权限允许时,可不创建对象,直接被类调用。
static注意点:
1、在静态的方法内,不能使用this关键字、super关键字
2、关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。
静态变量(类变量):
属性(成员变量):按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)。
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的
非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量(类变量): static修饰的变量为静态变量,所有的类的对象共享这个变量。我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
静态属性举例:System.out; Math.PI;
static修饰属性的其他说明:
1、 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
2、 静态变量的加载要早于对象的创建。
3、 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。 4、 静态成员属于整个类,当系统第 一次使用该类时,就 会为其分配内存空间直到该类被卸载才会进行资源回收。
例:
package com.hao.zhi.lv.MyStaticTest;
public class MyStaticTest {
static String device="500测序仪";
public static void main(String args[]){
System.out.println("用类名访问:"+MyStaticTest.device);
MyStaticTest myStaticTest1=new MyStaticTest();
System.out.println("用对象名访问:"+ myStaticTest1.device);
//改变属性值
MyStaticTest.device="2000测序仪";
System.out.println("属性值改变后用类名访问:"+ MyStaticTest.device);
//创建另一个对象,当通过某一个对象修改静态变量时其他对象调用此静态变量时,是修改过了的。
MyStaticTest myStaticTest2=new MyStaticTest();
myStaticTest2.device="50测序仪";
System.out.println("被myStaticTest2改变属性值后,myStaticTest1对象调用device+:"+myStaticTest1.device);
}
}
输出结果:
静态方法
与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。
静态方法的使用如:
package MyTest1;
public class MyTest14 {
public static void print(){
System.out.println("这是一个静态方法");
}
public static void main(String args[]){
//直接用类名调用静态方法
MyTest14.print();
//通过对象调用静态方法
MyTest14 myTest14=new MyTest14();
myTest14.print();
}
}
注:
静态方法中,只能调用静态的方法或属性。
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性。
具体如下:
1、 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:
如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:
package MyTest1;
public class MyTest15 {
String sunshine;//非静态变量
static String name;
public static void main(String args[]){
System.out.println(name);
// System.out.println(sunshine);
MyTest15 myTest15=new MyTest15();
System.out.println(myTest15.sunshine); //通过对象访问非静态变量
}
}
2、 在普通成员方法中(非静态方法),则可以直接访问同类的非静态变量和静态变量,例:
public void paly(){
System.out.println("非静态方法访问非静态变量:"+sunshine);
System.out.println("非静态方法访问静态变量:"+sunshine);
}
3、 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法,例:
package MyTest1;
public class MyTest15 {
String sunshine="非静态变量";//非静态变量
static String name="静态变量";
public static void main(String args[]){
System.out.println(name);
// System.out.println(sunshine);
MyTest15 myTest15=new MyTest15();
System.out.println(myTest15.sunshine); //通过对象访问非静态变量
listen();//静态方法可以直接访问静态方法
myTest15.paly();//静态方法访问非静态方法必须通过创建对象来调用
}
public static void listen(){
System.out.println("这是一个静态方法");
}
public void paly(){
System.out.println("非静态方法访问非静态变量:"+sunshine);
System.out.println("非静态方法访问静态变量:"+sunshine);
}
}
静态初始化块
Java 中可以通过初始化块进行数据赋值。如:
package MyTest1;
public class MyTest16 {
//定义一个成语变量
String sunshine;
//通过初始化块为成语变量赋值
{
sunshine="阳光很好";
}
}
在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用 static 修饰初始化块,就称为静态初始化块。
注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。
例:
package MyTest1;
public class MyTest16 {
String light1;//定义一个未初始化的非静态变量
String sunshine2;//定义一个未初始化的非静态变量
static String weather3;//定义一个未初始化的静态变量
public MyTest16(){
light1="光";
System.out.println("通过构造方法为变量light1赋值");
}
{
sunshine2="阳光很好";
System.out.println("通过初始化块为成员变量变量sunshine2赋值");
}
static {
weather3="天气超级好"; //静态化初始块
System.out.println("通过静态初始化为变量weather3赋值");
}
public static void main(String args[]) {
MyTest16 myTest16=new MyTest16();
System.out.println("light1:"+myTest16.light1);
System.out.println("sunshine2:"+myTest16.sunshine2);
System.out.println("weather3:"+weather3);
MyTest16 myTestN16=new MyTest16();
}
}
运行结果:
通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。由于静态初始化块只在类加载时执行一次,所以当再次创建对象 myTestN16时并未执行静态初始化块。
执行顺序:
参考来自慕课网、尚硅谷