1.先执行静态代码块
package com.ws;
public class Test1 {
public static void main(String[] args) {
System.out.println("这是main方法");
}
static {
System.out.println("这是静态代码块");
}
}
2.静态成员变量
public class Test1 {
static {
System.out.println("这是静态代码块");
}
static User user = new User();
public static void main(String[] args) {
System.out.println("这是main方法");
}
}
*静态代码的执行一定先与main方法,静态代码块和静态成员变量的执行顺序是有代码顺序决定的,谁在上面谁先执行。
3.非静态代码块和非静态变量
public class Test1 {
{
System.out.println("这是代码块");
}
User user = new User();
public static void main(String[] args) {
System.out.println("这是main方法");
}
}
代码块与成员变量,不执行。
*只有在创建Test1对象时才会执行非静态代码块和非静态成员变量,且执行顺序完全与位置有关,上面的先执行.
*(创建几次Test对象,就会执行多少次代码块,创建多少次成员变量)
public class Test1 {
{
System.out.println("这是代码块");
}
User user = new User();
public static void main(String[] args) {
System.out.println("这是main方法");
Test1 test1 = new Test1();
}
}
4、如果同时存在非静态代码块和静态代码块,以及非静态成员变量和静态成员变量,
*先执,行静态的东西,并且只执行一次,再执行非静态的东西(创建对象),创建多个对象就会执行多少次。
public class Test1 {
static {
System.out.println("这是静态代码块");
}
static User user = new User();
{
System.out.println("这是代码块");
}
User user1 = new User();
public static void main(String[] args) {
System.out.println("这是main方法");
Test1 test1 = new Test1();
Test1 test2 = new Test1();
}
}
5.加入父子类
public class Stub {
public Stub(String str) {
System.out.println(str + "created");
}
}
parent
public class Parent {
static Stub parentStaticStub = new Stub("parent static obj");
static {
System.out.println("这是parent静态代码块");
}
{
System.out.println("这是parent代码块");
}
Stub parentStub = new Stub("parent obj");
Stub stub;
public Parent() {
System.out.println("parent构造器");
Stub stub = new Stub("parent 构造器");
}
public void sayHello() {
System.out.println("hello from parent");
}
}
child
public class Child extends Parent{
static Stub parentStaticStub = new Stub("child static obj");
static {
System.out.println("这是child静态代码块");
}
{
System.out.println("这是child代码块");
}
Stub parentStub = new Stub("child obj");
Stub stub;
public Child() {
System.out.println("child 构造器");
Stub stub = new Stub("child 构造器");
}
@Override
public void sayHello() {
System.out.println("hello from child");
}
}
test
public class Test1 {
public static void main(String[] args) {
Child child = new Child();
child.sayHello();
((Parent)child).sayHello();
}
}
分析:
想要创建child对象首先要加载child类,又因为child继承parent,所以会优先加载parent类.
1.先加载parent类就会先执行parent类中的static块和static变量
2.然后会加载child类,执行child类中static块和static变量
3.类加载完成后,创建对象,优先创建parent对象,创建对象前先创建对象资源
4.执行parent构造器,完成parent对象创建
5.然后创建child对象,优先创建对象资源
6.执行child构造器,完成child对象创建
即使把child对象强转为parent,但内存中存储的还是child对象,所以依然会执行child的sayHello.
****************************************************************************************************
*static是被类的实例对象所共享
*static块在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
*被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。
*静态属于类,非静态属于对象(只有在创建对象时才会执行)