static关键字

static关键字

1.1 基本概念

  1. static意为静态,修饰类级别的属性和方法
  2. static修饰的变量称为静态变量,static修饰的方法称静态方法
  3. 静态变量/方法的特点:
    • 静态方法和静态变量都存储在JVM的方法区内存,通过“类名.” 的方式调用,不需要new一个实例对象
    • 静态变量/方法在类加载时初始化
    • 注意
      • 通过“引用.”的方式也可以调用只是不建议这样,因为会让程序员误以为是实例变量
      • 静态变量和静态方法不可能出现空指针异常,因为根本没有引用指向他们,直接通过“类名.”调用
public class StaticTest 
{
    public static void main(String[] args)
    {
        VarTest v=new VarTest();
        System.out.println(v.i);//调用实例变量i
        System.out.println(v.j);//通过“引用.”的方式调用静态变量j,可以但不建议
        System.out.println(VarTest.j);//通过“类名.”的方式调用静态变量j
      //System.out.println(VarTest.i);  通过“类名.”的方式调用静态变量i,报错,实例变量只能通过“引用.”的方式调用
     	  v.m1();//调用方法m1
        v.m2();//通过“引用.”的方式调用静态方法m2,可以但不建议
        VarTest.m2();//通过“类名.”的方式调用静态方法m2
      //VarTest.m1(); 通过“类名.”的方式调用方法m1,报错,实例方法只能通过“引用.”的方式调用
    }
}
class VarTest
{
    int i=10;
    static int j=11;
 	  public void m1()
    {
        System.out.println("方法m1正在被调用");
    }
    public static void m2()
    {
        System.out.println("静态方法m2正在被调用");
    }
}

1.2 静态变量的使用

public class StaticTest 
{
    public static void main(String[] args)
    {
       Chinese c1=new Chinese();
       Chinese c2=new Chinese();
       c1.name="张三";
       c1.idCard="21423432134";
       c2.name="李四";
       c2.idCard="90239459435";
       System.out.println(c1.idCard);
       System.out.println(c1.name);
       System.out.println(Chinese.country);

       System.out.println(c2.idCard);
       System.out.println(c2.name);
       System.out.println(Chinese.country);
    }
}
class Chinese
{
    String idCard;
    String name;
    static String country="中国";
}
  1. 静态变量最大的优点就是节省空间
  • 国籍使用非静态和静态变量的方式内存图比较:

在这里插入图片描述

在这里插入图片描述

  • 如图对于中国人这个类来说,国籍永远都是中国,如果用实例变量来表示,每次创建对象都会重新开辟一个空间,非常浪费空间,所以推荐使用静态变量

1.3 空指针异常

public class StaticTest 
{
    public static void main(String[] args)
    {
       Chinese c1=new Chinese();
       c1=null;
      // System.out.println(c1.name);//报错,空指针异常
       System.out.println(c1.country);//不报错,自动转换为“Chinese.country”
    }
}
class Chinese
{
    String name="zhangsan";
    static String country="中国";
}
  • 调用成员c1.name的时候空指针异常
  • 调用静态变量country的时候不报错,因为程序在执行该语句的时候会自动转换为“Chinese.country”在执行,跟c1无关

1.4 静态方法的使用

如果方法和实例变量密切相关,则不能用静态方法

  • 因为实例变量是需要new一个对象的,静态方法与对象无关
  • 只有方法与实例变量无关的时候可以用static修饰,变为静态方法

1.5 静态代码块

  1. 用static关键字可以定义静态代码块

  2. static代码块特点:

    • 只在类加载的时候执行一次

    • static代码块中可以访问静态变量(因为静态变量在类加载时期初始化)

      public class StaticTest
      {
        /*
          int k=10;
          static
          {
              System.out.println(k); //无法访问实例变量k,因为在类加载时,对象还没有被创建出来,不存在实例变量k
              System.out.println(l); //无法访问l,因为执行该代码块的时候l还没有定义
          }
          static int l=20;  
        */
          public static void main(String[] args)
          {
              System.out.println("main begin");
          }
      }
      
    • 静态变量和静态代码块是按编写顺序执行的

      • 如图,静态代码块在静态变量l前,先执行静态代码块,在定义静态变量l,所以无法访问l

      • 如果在静态代码块之前定义静态变量l,就可以访问了

      • 实例变量k在创建实例对象的时候才会生成,在类加载之后,所以也不能访问

    • 静态代码块是按编写顺序执行的

      public class StaticTest
      {
          static//静态代码块
          {
              System.out.println("A");
          }
          static
          {
              System.out.println("B");
          }
          public static void main(String[] args)
          {
              System.out.println("D");
          }
          static
          {
              System.out.println("C");
          }
      }
      

      该代码输出顺序:ABCD

3.静态代码块作用

  • 项目需求中需要在类加载时刻记录信息时,可利用该代码

1.6 实例代码块

public class InstanceCode 
{
    public static void main(String[] args)
    {
        System.out.println("main begin");
        new InstanceCode();
        new InstanceCode(1);
    }
		//实例代码块
    {
        System.out.println("调用实例代码块");
    }

    public InstanceCode()
    {
        System.out.println("调用无参数的构造方法");
    }
    public InstanceCode(int a)
    {
        System.out.println("调用有参数的构造方法");
    }
}

输出结果:

  • 调用实例代码块
    调用无参数的构造方法
    调用实例代码块
    调用有参数的构造方法

1.实例代码块执行时机:

  • 每次构造函数调用前都先执行实例代码块,在调用构造函数

    无论实例代码块写在构造函数前后,都是如此

2.实例代码块作用:

  • 为程序员节省时间
    • 如果编写了很多构造函数而且开头一部分代码都相同,就可以把相同部分写在实例代码块里
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值