引例:
想象一下一间屋子里面的人要喝水,房间里面只要有一个饮水机供大家共享使用即可,在java中被共享的对象或者方法需要用到static修饰。(应用:用户创建对象的次数的计数器)
static**(静态\修饰符)
1. static修饰成员变量 :
如果有数据需要被共享给所有对象使用时,那么就可以使用static修饰。
静态成员变量的访问方式:
方式1: 可以使用对象进行访问。
格式: 对象.变量名。
方式2: 可以使用类名进行访问。
格式: 类名.变量名。
注意:
1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
static修饰成员变量的应用场景: 如果一个数据需要被所有对象共享使用的时候,这时候即可好实用static修饰。
2. static修饰成员函数
注意事项:
1.静态函数是可以调用类名或者对象进行调用的,而非静态函数只能使用对象进行调用。
2.静态的函数可以直接访问静态的成员,但是不能直接访问非静态成员。
原因:静态函数是可以使用类名 直接调用的,这时候可能还没有存在对象,
而非静态的成员数据是随着对象的创建而存在。
3.非静态的函数是可以直接访问静态与非静态的成员。
原因:非静态函数只能由对象调用,当对象存在的时候,静态数据老早就已经存在了,而非静态数据也随着对象的创建而存在了。
4.静态函数不能出现this或者super关键字。
原因:因为静态函数可以使用类名调用,一旦使用类名调用,这时候不存在对象,而this关键字是代表了一个函数的调用对象,这时候产生了冲突。
静态的数据生命周期:静态的成员变量数据是优先于对象存在的。
静态的成员变量与非静态的成员变量的区别
1. 作用上的区别:
1.静态的成员变量的作用共享一个数据所有的对象使用。
2.非静态的成员变量的作用是描述一类事物的公共属性。
2.数量与存储位置上的区别:
1.静态成员变量存在于内存中的方法区,而且知乎存在一份数据。
2.非静态的成员变量是存储在堆内存中,有n个对象就有n份数据。
3.生命周期的区别:
1.静态的成员变量数据是随着类的加载而存在,随着类文件的消失而消失。
2.非静态的成员数据是随着对象的创建而存在,随着对象垃圾回收器回收而消失。
main函数的详解:
public static void main(String[] args)
public : 公共的,权限最大,在任何情况下都可以访问。
main函数设置成public是为了保证JVM在任何情况下都可以访问到main,如果是private的话,那JVM就不能调用main函数了。
static:静态
好处:main函数设置成static之后,JVM在调用类时直接在类名后面加.class即可访问。
弊端:a.如果不用static修饰,JVM需要先创建对象后再使用main函数;b.JVM不知道如果创建对象,因为创建对象时有些是需要参数的,参数传递什么东西呢?这个问题JVM无法解决。
void:空
main函数无返回值,因为返回的数据是给JVM 的,而JVM用不上这个返回值。(程序已经运行结束了,要参数干嘛)
main:函数名
main并不是关键字,只不过是JVM能识别的一个特殊的函数名而已。
arguements:参数
设置args 形参目的:担心某些程序在启动时需要参数。
并不常用,因为只能输入一次参数,在程序真正运行时可能需要多次输入数据。
常用:
Scanner scanner = new Scanner(System.in);
// scanner.hasNextInt();
静态数据的内存图
class Student{
String name; //非静态成员变量
static String country = "中国"; //静态的成员变量
public Student(String name){
this.name = name;
}
}
class Demo10 {
public static void main(String[] args)
{
Student s1 = new Student("狗娃");
Student s2 = new Student("狗剩");
//System.out.println("国籍:"+ Student.country);
System.out.println("名字:"+ s1.name);
System.out.println("名字:"+ s2.name);
}
}
case:
/*
需求: 统计一个类被使用了多少次创建对象,该类对外显示被创建的次数。
*/
class Emp{
//非静态的成员变量。
static int count = 0; //计数器
String name;
//构造代码块
{
count++;
}
public Emp(String name){
this.name = name;
}
public Emp(){ //每创建一个对象的时候都会执行这里 的代码
}
public void showCount(){
System.out.println("创建了"+ count+"个对象");
}
}
class Demo11
{
public static void main(String[] args)
{
Emp e1 = new Emp();
Emp e2 = new Emp();
Emp e3 =new Emp();
e3.showCount();
}
}