目录
有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩?,编写程序解决。

针对这样的问题我们可以这样写:
- public class ChildGame {
-
- public static void main(String[] args) {
-
- //定义一个变量 count,统计有多少个小孩加入游戏
- int count=0;
-
- Child child01 = new Child("白骨精");
- child01.join();
- count++;
-
- Child child02 = new Child("狐狸精");
- child02.join();
- count++;
-
- Child child03 = new Child("老鼠精");
- child03.join();
- count++;
-
- //==============
- System.out.println("共有"+count+"个小孩加入了游戏!");
- }
-
- }
-
- class Child{
- private String name;
-
- public Child(String name) {
- this.name = name;
- }
-
- public void join(){
- System.out.println(name+" 加入了游戏...");
- }
- }

但是我们这样写会有什么问题?思路有了,代码也实现了,但是这样写带来的问题:

对于这个问题最主要是:这个变量不属于所有对象
这时候延伸出一个静态变量
- public class ChildGame {
-
- public static void main(String[] args) {
-
- //定义一个变量 count,统计有多少个小孩加入游戏
- int count=0;
-
- Child child01 = new Child("白骨精");
- child01.join();
- // count++;
- child01.count++;
-
- Child child02 = new Child("狐狸精");
- child02.join();
- // count++;
- child02.count++;
-
- Child child03 = new Child("老鼠精");
- child03.join();
- // count++;
- child03.count++;
-
- //==============
- //静态变量可以通过类名来访问
- System.out.println("共有"+ Child.count +"个小孩加入了游戏!");
- }
-
- }
-
- class Child{
- private String name;
- //定义一个变量count,是一个类变量(静态变量)-->static
- //该变量的最大特点就是会被Child类的所有对象实例共享
- public static int count = 0;
-
- public Child(String name) {
- this.name = name;
- }
-
- public void join(){
- System.out.println(name+" 加入了游戏...");
- }
- }



从图中可以直观感受:两个对象共享的一个数据,存放count的这个空间是个堆空间。
静态变量是被所有对象实例共享的

在JDK 8之前,这个count静态变量是在方法区里的静态域,JDK 8或者之后,是放在堆里面的,通过反射机制,会加载一个class对象。
当类进行加载的时候,会在堆生成的class对象,通过这个对象可以拿到很多类的信息。
也就是说在JDK 8以后,通常的认为静态变量在堆里面的这个类对应的Class对象的最后。
在面试的时候说清楚这一点就行了。不管是在堆还是静态域,这里不会影响我们对静态变量的使用。
静态变量的核心是:1.被所有对象共享的。2.在类加载的时候就生成。



- public class VisitStatic {
-
- public static void main(String[] args) {
-
- //类名.类变量名
- //说明:类变量是随着类加载而创建的,所以即使没有创建对象实例,也可以访问。
- System.out.println(A.name); //输出:GodAiro
-
- A a = new A();
- //通过对象名.类变量名
- System.out.println("a.name="+a.name); //输出:a.name=GodAiro
- }
- }
-
- class A{
- //类变量
- public static String name = "GodAiro";
- }



- public class StaticMethod {
- public static void main(String[] args) {
- Student student1 = new Student("godairo");
- student1.payFee(100);
-
- Student student2 = new Student("tom");
- Student.payFee(200);
-
- Student.showFee(); //总学费有:300.0
- }
- }
-
- class Student{
-
- private String name; //普通成员
-
- //定义一个静态变量,来累积学生的学费
- private static double fee = 0;
-
- public Student(String name) {
- this.name = name;
- }
-
- /**
- * 1.当方法使用static修饰后,该方法就是静态方法
- * 2.静态方法就可以访问静态属性/变量
- */
- public static void payFee(double fee){
- Student.fee +=fee; //累积到静态变量里的fee
- }
-
- public static void showFee(){
- System.out.println("总学费有:"+Student.fee);
- }
-
- }

也就是说我们不用创建一个对象,就能使用其中的方法
- //如果我们希望不创建实例,也可以调用某个方法(即当做工具来使用)
- //这时,把方法做成静态方法时非常合适
- System.out.println("9开平方的结果是="+Math.sqrt(9)); // 3.0
- //开发自己的工具类时,可以将方法做成静态的,方便调用
- class MyTools{
- //求出两个数的合
- public static double calSum(double n1,double n2){
- return n1+n2;
- }
- }
-
- public static void main(String[] args) {
- System.out.println(MyTools.calSum(1,2)); //3.0
- }



因为是后++,那么就是先输出一个9,然后进行++。
然后又创建匿名对象,然后调用count方法,那么会先输出count的值:10,然后自增,此时count变成了11。
那么最后用类名.属性名去访问count的值,最后值就是11。

这里在静态getTotalPerson()方法里是不能访问普通属性,也就是id,这里我们直接注释掉就行。
而在构造器Person里面可以访问所有成员。
那么直接通过类调用getTotalPerson()方法,这里直接输出0。
当我们new了一个Person对象,构造器里面total自增,变成了1,此时还把total赋给了id,id也变成了1,这时候再去通过类调用getTotalPerson()方法,此时的值为1

在static方法中,不能用this,把形参total的值赋给静态变量的值可以这样写:Person.total=total;