使用场景如下:
一、修饰变量和方法;
1.被static修饰后的变量和方法均属于类,在调用的时候可以使用类名.变量或者类名.方法;
package cn.yj.lpp;
public class StaticTest {
public static void method(){
System.out.println("我这个是静态方法");
// System.out.println(name); 这里报错:非静态域name不能被静态上下文引用
}
public String name = "Galagher";
public static void main(String[] args) {
StaticTest sta = new StaticTest();
sta.method(); //输出:我是个静态方法
StaticTest.method(); //输出:我是个静态方法
System.out.println(sta.name); //输出:Gallagher
// System.out.println(StaticTest.name);这里报错:非静态域name不能被静态上下文引用
}
}
代码中还说明了:静态方法不能调用非静态变量,非静态可以条用静态方法或者变量;当让静态肯定是可以调用静态滴;
原因是:静态资源(方法或者变量)是在类初始化的时候加载的,但是非静态资源是类new的时候加载的。类的初始化早于类的new;
所以这里如果静态去调用非静态的时候,可能会出现非静态还没有产生,这样就不能实现调用。
二、静态代码块
静态代码块只执行一次,执行时间是在类进行加载时就开始执行;
static{
sout("这里是静态代码块");
}
//注意执行时间:类加载时;执行次数:仅一次;
这里我们来讨论一下类中资源加载顺序:
package cn.yj.lpp;
public class FuTest {
public FuTest() {
System.out.println("我是父类构造方法");
}
static {
System.out.println("我是父类静态代码块");
}
public void nomalzimethod(){
System.out.println("我是父类普通方法,会被子类覆盖"); //这里就不会调用
}
{
System.out.println("我是父类非静态代码块");
}
{
System.out.println("插一嘴,父类普通和父类静态没差");
}
}
package cn.yj.lpp;
public class ZiTest extends FuTest {
public ZiTest(){
System.out.println("我是子类构造方法");
}
static {
System.out.println("我是子类静态代码块");
}
public static void staticzimethod(){
System.out.println("我是子类静态方法");
}
{System.out.println("我是子类非静态代码块");}
public void nomalzimethod(){
System.out.println("我是子类普通方法,需要对象调用");
}
public static void main(String[] args) {
System.out.println("我是子类main方法");
ZiTest zi = new ZiTest();
zi.nomalzimethod();
}
}
输出为:
我是父类静态代码块
我是子类静态代码块
我是子类main方法 //这里是程序入口
我是父类非静态代码块
插一嘴,父类普通和父类静态没差
我是父类构造方法
我是子类非静态代码块
我是子类构造方法
我是子类普通方法,需要对象调用 //这里是因为要使用对象调用,而构造方法作为初始化对象的作用,就要
//先于子类普通方法执行
Process finished with exit code 0
总的来说,执行顺序是:
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造方法
子类非静态代码块
子类构造方法
子类普通方法
三、修饰成员变量的作用域
虽然java语言中没有全局的概念,但可以通过static关键字来达到全局的效果。java类提供了两种类型的变量:用static关键字修饰的静态变量和没有static关键字修饰的实例变量。静态变量属于类,在内存中只有一个副本(所有势力都指向同一个内存地址)。只要静态变量所在的类被加载,这个静态类就会被分配空间,因此就可以被使用。static修饰的变量就属于共享数据,当发生改变时,全局的这个变量都会发生改变。对静态变量的引用有两种方式,分别为“类.静态变量”和“对象.静态变量”。实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才能被使用,他在内存中存在多个副本,只能用“对象.静态变量”的方式来引用。静态变量只有一个,被类所拥有,所有的对象都共享这个静态变量,而实例对象与具体对象有关。
四、静态内部类
内部类被static修饰成为静态内部类:
如果被静态修饰后,访问内部类的成员:Outer.Inner oi = new Outer.Inner();
被静态修饰的成员内部类只能访问外部类的静态成员 内部类被静态修饰后的方法有静态和非静态之分,他们的访问和不用静态是不一样的
(1)访问非静态方法:show() Outer.Inner oi = new Outer.Inner(); oi.show();
(2)访问静态方法:show2() 方式1: Outer.Inner oi = new Outer.Inner(); oi.show2();
方式2:不创建对象,直接通过类名访问 Outer.Inner.show2();
五、成员变量和静态变量的区别:
1、生命周期的不同:
成员变量随着对象的创建而存在随着对象的回收而释放。
静态变量随着类的加载而存在随着类的消失而消失。
2、调用方式不同:
成员变量只能被对象调用。
静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用)
3、别名不同:
成员变量也称为实例变量。
静态变量称为类变量。
4、数据存储位置不同:
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
(3)静态使用时需要注意的事项:
1、静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)
2、静态方法中不可以使用this或者super关键字。
3、主函数是静态的
六、静态导包
未完待续。。。