1.static(静态)
1)静态方法:该函数没有访问对象中的属性时,就要用static修饰
如果xxx()方法没有使用对象中的数据,那么创建对象调用该方法是没有意义的,只会占用内存一片存储区域
上述xxx()方法通过修饰符static修饰后可用类名直接调用该方法(当然也可以通过对象进行调用)
2)静态变量:类中对象所共享的属性,就用static修饰
它存储在方法区(数据共享区)的静态代码区内,相对于非静态变量存储于堆区的对象中节省了空间
通过static修饰的静态变量可通过类名直接调用(当然也可通过对象进行调用)
class Person{
private String name;
private int age;
static String country = "China";//静态成员变量
Person(String name,int age){
this.name = name;
this.age = age;
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
public static void sleep(){
System.out.println("zZZ...");
}//静态方法
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person("xiaoxiao",20);
p.show();
Person.sleep();//类中的静态方法通过类名的形式调用
p.sleep();//静态方法通过对象的形式进行调用
System.out.println(Person.country);//静态成员变量通过类名的形式调用
System.out.println(p.country);//静态成员变量通过对象的形式调用
p.country = "English";//通过对象的形式进行修改静态成员变量
System.out.println(p.country);
Person.country = "America";//通过类名的形式进行修改静态成员变量
System.out.println(p.country);
}
}
总结:
static:成员修饰符
特点:
1)被静态修饰的成员,可以直接被类名所调用
2)静态成员优先于对象的存在
3)静态成员随类的加载而加载,随着类的消失而消失,静态成员生命周期很长
注意:
1)静态方法只能访问静态成员,不能访问非静态成员。静态方法访问的局限性
2)静态方法中不能出现this和super关键字,(this是对象的引用,而静态方法优先于对象存在)
3)主函数是静态的,主函数所在类中定义的非静态成员是不能被主函数访问的。
成员变量和静态变量的区别(静态static只能修饰成员):
1)成员变量也叫实例变量(由对象调用),静态变量也叫类变量(由类调用)
2)成员变量存储在堆区的对象中,静态变量存储在方区的静态区中
3)成员变量随着对象的出现而出现,随着对象的消失而消失;静态变量随着类的出现而出现,随着类的消失而消失
2.静态代码块:随着类的加载而执行,而且只执行一次
作用:给不需要创建对象的类进行初始化
class StaticCode{
static int num=0;
static {//静态代码块
num++;
System.out.println("C");
}
static void show(){
System.out.println(num);
}
}
class StaticCodeDemo
{
public static void main(String[] args)
{
StaticCode.show();
StaticCode.show();
}
}
3.构造代码块:非静态代码块,给所有对象进行初始化。(构造函数只给对应对象初始化)
class StructCode{
private int age = 8;//显示初始化
{//构造代码块
System.out.println("构造代码块run"+"age = "+age);//显示初始化在构造代码快执行前执行
cry();//将所有对象共有行为抽取出来
}
StructCode(){
System.out.println("构造函数run");
}
public void cry(){
System.out.println("WaWa...");
}
}
class StructCodeDemo
{
public static void main(String[] args)
{
StructCode s1 = new StructCode();
StructCode s2 = new StructCode();
StructCode s3 = new StructCode();
}
}
4.创建一个对象的流程
1)加载指定的字节码文件进入内存
2)通过new在堆内存中开辟空间,分配首地址值
3)对对象中的属性进行默认初始化
4)调用与之对应的构造函数,构造函数压栈
5)构造函数中执行隐士的语句super()访问父类中的构造函数
6)对属性进行显示初始化
7)调用类中的构造代码块
8)执行构造函数中自定义的初始化代码
9)初始化完毕,将地址值赋给指定的引用