- 1. static关键字
- 1.1概述
- 1.2修饰一个成员变量
- 例:
- 1.2.1静态属性与非静态属性示例及内存图对比
- 1.3修饰一个方法(静态方法)
- 1.4.static修饰成员的访问特点总结
- 1.5动态代码块和静态代码块
- 1.5.1动态代码块
- 1.5.2 静态代码块
- 1.6带有继承的对象创建过程
1. static关键字
1.1概述
1.概述:static是一个静态关键字
2.使用:a.修饰一个成员变量:static 数据类型 变量名b.修饰一个方法:修饰符 static 返回值类型 方法名(形参){方法体return 结果}3.调用静态成员:类名直接调用(不用new对象)4.静态成员特点:a.静态成员属于类成员,不属于对象成员(非静态的成员属于对象成员)b.静态成员会随着类的加载而加载c.静态成员优先于非静态成员存在在内存中d.凡是根据静态成员所在的类创建出来的对象,都可以共享这个静态成员
1.2修饰一个成员变量
例:
public class Student {String name;int age;static String classRoom;
}
public class Test01 {public static void main(String[] args) {//先给静态成员赋个值 类名直接调用(不用new对象) Student.classRoom = "222";Student s1 = new Student();s1.name = "郭靖";s1.age = 28;//s1.classRoom = "111";System.out.println(s1.name+","+s1.age+","+Student.classRoom);System.out.println("==============");Student s2 = new Student();s2.name = "黄蓉";s2.age = 26;//s2.classRoom = "111";System.out.println(s2.name+","+s2.age+","+Student.classRoom);}
}
1.2.1静态属性与非静态属性示例及内存图对比
public class MyClass {public int a; //实例属性
}public class MyTest1 {public static void main(String[] args) {MyClass c1 = new MyClass();c1.a = 20;MyClass c2 = new MyClass();c2.a = 30;System.out.println("c1.a = " + c1.a);System.out.println("c2.a = " + c2.a);}
}
实例属性是每个对象各自持有的独立空间,对象单方面修改,不会影响其他对象。
public class MyClass {public int a;//实例属性public static int b;//静态属性
}public class MyTest2 {public static void main(String[] args) {//static修饰的变量随着类的加载而存在,和是否创建对象无关。MyClass.b = 10;System.out.println(MyClass.b);System.out.println("==========================");MyClass c1 = new MyClass();MyClass c2 = new MyClass();System.out.println("c1.b = " + c1.b);System.out.println("c2.b = " + c2.b);System.out.println("==========================");c1.b = 1000;System.out.println("c1.b = " + c1.b);System.out.println("c2.b = " + c2.b);}
}
静态属性是整个类共同持有的共享空间(只有一份),任何对象修改静态属性,都会影响其他对象对该属性的访问。
static修饰的变量随着类的加载而存在,和是否创建对象无关。
1.3修饰一个方法(静态方法)
public class MyClass {public int a;public static int b;//由static修饰的静态方法public static void m1() {//在本类中,可以通过"静态方法名"访问m2();System.out.println("m1....");}//由static修饰的静态方法public static void m2() {System.out.println("m2....");}
}public class MyTest2 {public static void main(String[] args) {//在其他类中,可以通过"类名.静态方法名"的方式访问静态方法MyClass.m1();}
}
关于静态的注意事项:
静态方法允许值访问静态成员; 想要调用的话:new对象调用
静态方法不能直接访问非静态成员;
静态方法中不允许使用this或是super关键字。
1.4.static修饰成员的访问特点总结
1.在静态方法中能直接访问非静态成员嘛? 不能想要调用的话:new对象调用 2.在非静态方法中能直接访问静态成员嘛? 能a.同类:直接调用类名调用b.不同类:类名调用3.在静态方法中能直接访问静态成员嘛?能a.同类:直接调用类名调用b.不同类:类名调用4.在非静态方法中能直接访问非静态成员嘛?能a.同类:直接调用new对象调用b.不同类:new对象调用
1.5动态代码块和静态代码块
1.5.1动态代码块
定义在类中,与属性和方法处于同一级。
语法:
class 类名 {{//动态代码块}
}
创建对象时,触发动态代码块的执行(创建一次,执行一次)。
执行时机:
动态代码块和实例属性的初始化顺序,由在类中书写的顺序决定;
代码块和属性的初始化先于构造方法执行。
作用:可为实例属性赋值,或必要的初始行为。
public class X {public X() {System.out.println("实例属性");}
}public class MyClass1 {private X x = new X();//动态代码块{System.out.println("动态代码块");}public MyClass1() {System.out.println("构造方法...");}
}public class MyTest3 {public static void main(String[] args) {MyClass1 c1 = new MyClass1();System.out.println("-------------------------");MyClass1 c2 = new MyClass1();}
}
执行结果
实例属性
动态代码块
构造方法...
-------------------------
实例属性
动态代码块
构造方法...
1.5.2 静态代码块
定义在类中,与属性和方法处于同一级。
语法:
class 类名 {static {//静态代码块}
}
类加载时,触发静态代码块的执行(仅一次)。
执行时机:
静态属性和静态代码块,二者优先级相同,执行顺序由定义顺序决定
代码块和属性的初始化先于构造方法执行。
作用:可为静态属性赋值,或必要的初始行为。
public class Y {public Y() {System.out.println("静态属性");}
}public class MyClass2 {private static Y y = new Y();//静态代码块static {System.out.println("静态代码块");}public MyClass2() {System.out.println("构造方法...");}
}public class MyTest4 {public static void main(String[] args) {MyClass2 c1 = new MyClass2();System.out.println("+++++++++++++++++++++++++++");MyClass2 c2 = new MyClass2();}
}
执行结果
静态属性
静态代码块
构造方法...
+++++++++++++++++++++++++++
构造方法...
对象创建过程
public class X {public X() {System.out.println("实例属性");}
}public class Y {public Y() {System.out.println("静态属性");}
}public class MyClass3 {private X x = new X();private static Y y = new Y();//动态代码块{System.out.println("动态代码块");}//静态代码块static {System.out.println("静态代码块");}public MyClass3() {System.out.println("构造方法...");}
}public class MyTest5 {public static void main(String[] args) {MyClass3 c1 = new MyClass3();System.out.println("==========================");MyClass3 c2 = new MyClass3();}
}
执行结果
静态属性
静态代码块
实例属性
动态代码块
构造方法...
==========================
实例属性
动态代码块
构造方法...
1.6带有继承的对象创建过程
public class X {public X() {System.out.println("父类实例属性");}
}public class Y {public Y() {System.out.println("父类静态属性");}
}public class M {public M() {System.out.println("子类实例属性");}
}public class N {public N() {System.out.println("子类静态属性");}
}public class SuperClass {private X x = new X();private static Y y = new Y();//动态代码块{System.out.println("父类动态代码块");}//静态代码块static {System.out.println("父类静态代码块");}public SuperClass() {System.out.println("父类构造方法...");}
}public class SubClass extends SuperClass {private M m = new M();private static N n = new N();//动态代码块{System.out.println("子类动态代码块");}//静态代码块static {System.out.println("子类静态代码块");}public SubClass() {System.out.println("子类构造方法...");}
}public class MyTest6 {public static void main(String[] args) {SubClass subClass = new SubClass();System.out.println("***************************");SubClass subClass1 = new SubClass();}
}
这里是引用
执行结果
父类静态属性
父类静态代码块
子类静态属性
子类静态代码块
父类实例属性
父类动态代码块
父类构造方法...
子类实例属性
子类动态代码块
子类构造方法...
***************************
父类实例属性
父类动态代码块
父类构造方法...
子类实例属性
子类动态代码块
子类构造方法...