成员变量+static=静态变量
为什么要用静态成员变量呢?
当我们在设计类的时候 发现多个对象中有共享数据的时候 我们就可以把这个共享的数据 定义为静态的
对象的特有数据称为成员变量,对象的共有数据称为静态变量
静态的东西从堆中对象的空间里抽取出来了放到静态方法区(共有的数据存在于一个特定的空间称为静态方法区)
静态变量的生命周期大于成员变量
成员函数+static=静态函数
我们当前的成员函数如果不访问任何成员变量的情况下 这个函数就可以定义为静态的----定义静态函数的唯一标准
注:静态变量代表 对象的共有数据,但是静态函数不代表对象的共有行为
1.被static关键字修饰的方法一般被称为静态方法 没有被static关键字修饰的方法 一般称为非静态方法。同理 被static关键字修饰的成员变量 叫静态的成员变量 ,没有被static修饰的叫非静态成员变量
2.静态方法 只能访问静态的成员变量 ,无需创建对象,使用类名就可以直接调用;如果访问非静态成员变量 那么无法通过编译,
public class Stc{
public static int j;
public static void main(String[] args){
System.out.println(Stc.getII());
System.out.println(Stc.j);
}
public static int getII(){
return j;
}
}
对象.变量一般有两种情况:
(1)先去堆内存中对象的所属空间去找
(2)再去静态方法区中该对象所属类的空间中去找
对象.函数一般也有两种情况
(1)先去非静态方法区中该类所属空间里找
(2)再去静态方法区中该类所属空间里找
成员函数内部在调用变量时的顺序:(就近原则,谁近调谁)
1.先找局部变量
2.去堆中对象空间中找
3.去静态区该对象所属类的空间里找静态优先于对象存在 静态也称之为类的成员 也就意味着我们可以通过类直接去调用---类.静态成员
代码如下:
class Static{
public static void main(String[] args){
Chinese c1=new Chinese();
Chinese c2=new Chinese();
Chinese c3=new Chinese();
//对象.变量
//1.先去堆内存中对象的所属空间里找
System.out.println(c1.name); //成员变量
//2.再去静态方法区中该对象所属类的空间里找
System.out.println(c1.country); //静态变量
//对象.函数
//1.先去非静态方法区中该类所属空间里找
c1.show();
//2.再去静态方法区中该类所属空间里找
c1.haha();
//类.静态成员
System.out.println(Chinese.country);
//类.静态方法
System.out.println(Chinese.haha);
}
}
class Chinese{
String name; //姓名
String age; //年龄
static String country="China"; //国籍
public void show(){
/*
成员函数内部在调用变量时的顺序:
1.先找局部变量
2.去堆中对象空间中找
3.去静态区该对象所属类的空间里找
*/
System.out.println(name+age+country);
}
public static void haha(){
System.out.println("哈哈");
}
}
3.非静态方法 既能访问静态的成员变量,也能访问非静态的成员变量 只能通过创建对象的方式进行调用
为什么主函数是静态的?
主函数是程序的入口,优于其它运行
假设主函数是非静态的 那么必须先创建对象 才能调用主函数
public class Stc{
public int i;
public static int j;
public static void main(String[] args){
//非静态方法--通过创建对象进行调用和访问
Stc s=new Stc();
System.out.println(s.getI());
System.out.println(s.getII());
}
public int getI(){//非静态方法
return i;
}
public int getII(){//非静态方法
return j;
}
}
4.被static修饰的内容 在代码程序中会按照顺序进行加载, 如果主函数在下面,那么会优先加载静态成员变量和成员方法
/**
被static修饰的会优于主函数执行,先执行static修饰的
*/
public class Count{
private static Count c=new Count();//创建静态的对象--4
private static int count1;//5
private static int count2=0;//6
public Count(){//构造函数---1
count1++;//2
count2++;//3
}
public static Count getInstance(){//9
return c;//10
}
public static void main(String[] args){//7
Count c=Count.getInstance();//8
System.out.println("count1:"+count1);//11
System.out.println("count2:"+count2);//12
}
}
5.static静态代码块只执行一次 且静态代码块是优先其他加载 static的执行顺序,按代码的先后顺序执行
构造代码块:直接在类中出现的{...}
当对象创建一次 构造代码块执行一次
作用等同于构造函数静态代码块:直接在类中出现的static{...}
当类被加载的时候 仅且只执行一次
作用于对类进行一些初始化操作
//如果主函数在下面,会优先加载静态的成员变量和方法
public class Per{
private String name;
private int age;
private String sex;
static{//静态代码块 被static修饰的代码块,按顺序加载
System.out.println("000");
}
private static Per p=new Per();
public Per(){
System.out.println("111");
}
public Per(String name){
this();//调用上面无参的构造函数
this.name=name;
System.out.println("123");
}
public Per(String name,int age){
this(name);//调用上面无参的构造函数
this.name=name;
this.age=age;
System.out.println("456");
}
public Per(String name,int age,String sex){//对象找到的是此构造器
this();//调用上面两个参数的构造函数
this.name=name;
this.age=age;
this.sex=sex;
System.out.println("789");
}
public void setAge(int age){//将局部变量的值传递给成员变量 不需要返回
this.age=age;//this后面是成员变量 右边是局部变量 将局部变量的值给成员变量
}
public int getAge(){
return age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setSex(){
this.sex=sex;
}
public String getSex(){
return sex;
}
public static void main(String[] args){
Per p=new Per("张三",20,"男");
}
}
6.静态方法和静态成员变量 被整个程序共用 相当于共享
7.静态变量与成员变量的区别
(1.)生命周期
成员变量随着对象的创建而创建 随着对象的消亡而消亡
静态变量随着类的加载而创建 随着程序结束而消失
(2.)调用方式
成员变量必须先创建对象 在通过对象去调用
静态变量可以被对象调用 也可以直接用类调用
(3.)存储位置
成员变量存在于堆内存中对象的所属空间里
静态变量存在于静态方法区中类的所属空间里
(4.)命名
成员变量-对象的特有属性
静态变量-对象的共有属性 类成员
8.静态函数中不会存在this关键字-----原因是静态函数优先于对象存在,而有了对象才会有this
9.静态变量,我们在定义时候,一般而言这个变量是不可修改的,一般会加上final修饰