[java基础]static关键字、代码块和执行顺序

static关键字应用在回避实例化对象和公共属性的场景
static全局属性可以应用在无参构造方法中进行计数

static属性 解决重复数据的修改不方便

1.类的属性存储在各自的堆内存中,static属性存储在全局数据区
2.可提出公共属性用static修饰,则一旦修改属性所有对象中的属性均会修改
3.static属性可在类未实例化时通过 类名.属性 使用,非static属性必须在实对象实例化后使用
4.私有静态变量在类外无法直接访问,必须通过类内的public方法才可访问和修改

class Another {
    private static int y = 8;
}

public class Test {
    private static int x = 3;
    public static void main(String[] args) {
        x++; // 主方法静态方法,可直接访问主类中的private static属性
        Test.x++; // 本类私有静态变量可通过类名调用
        new Test().x++; // 本类私有静态变量可通过对象调用
        // y++; 无法直接访问外部类中的private static属性
        // Another.y++; 无法通过类名访问外部类私有静态变量
        // new Another().y++; 无法通过对象访问外部类私有静态变量
    }
}

静态变量存储在全局区域,实例化不会创建新的静态变量

public class Test {
    private static int x = 3;
    public static void main(String[] args) {
        Test.x++;   // 4
        new Test().x++; // 5
        new Test().x++; // 6
    }

static方法

1.static属性一般封装,由public static方法实现属性的访问和修改,方法中不使用this关键字(this只有在实例化后才能访问)
2.无论实例化对象与否均可使用,类名称.方法()实例.方法()
3.static方法只允许调用static属性和static方法(若调用非static属性和方法通过实例化类来访问和修改)
4.非static方法允许调用static属性和static方法
5.类中的static方法称为 类方法,类中的普通方法称为 实例方法

代码块执行顺序

  • 普通代码块 普通方法中可用{}拆分代码
    方法中进行结构的拆分,防止相同变量名称的相互影响
  • 构造代码块 定义在类中的代码块,区别于构造方法
    实例化时执行,构造块优先于构造方法执行
  • 静态代码块 static关键字定义的代码块
    一般用于进行类中静态属性的初始化
public class Custom{
    public Custom{
        System.out.println("构造方法最后执行");
    }
    {
        System.out.println("构造块在静态块后执行");
    }
    static{
        System.out.println("静态块最先执行且只执行一次");
    }
}

public static void main(String[] args){
    new Custom();
    new Custom();
    new Custom();
}

在非主方法所在类进行静态块定义

静态块最先执行且只执行一次
构造块在静态块后执行
构造方法最后执行
构造块在静态块后执行
构造方法最后执行
构造块在静态块后执行
构造方法最后执行

主类中进行静态块定义

静态代码块优先于主方法执行

涉及继承的执行顺序

父类静态变量
父类静态代码块
子类静态变量
子类静态代码块
父类非静态变量
父类非静态代码块
父类构造方法
子类非静态变量
子类非静态代码块
子类构造方法

成员变量总是最先执行,同级按顺序执行,
构造方法重载只执行调用方法默认执行无参

被动引用问题

1.子类引用父类静态属性,初始化父类,不初始化子类

    public class P {
        public static int abc = 123;
        static{
            System.out.println("P is init");
        }
    }

    public class S extends P {
        static{
            System.out.println("S is init");
        }
    }

    public class Test {
        public static void main(String[] args) {
            System.out.println(S.abc);
        }
    }

2.数组定义引用类,类不初始化

    public class NotInitialization {
        public static void main(String[] args) {
            SuperClass[] sca = new SuperClass[10];
        }
    }

3.静态变量在编译阶段存入静态池中,定义类变量的类不初始化

    public class ConstClass {
        public static final int value = 123;
        static {
            System.out.println("ConstClass init!");
        }
    }

    public class NotInitialization{
        public static void main(String[] args) {
            int x = ConstClass.value;
        }
    }

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

©2018-2024 Howell版权所有 备案号:冀ICP备19000576号