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;
}
}