目录
1. 类变量-提出问题
有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩?,编写程序解决。
2. 传统的方法来解决
3. 类变量快速入门
针对这样的问题我们可以这样写:
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+" 加入了游戏...");
}
}
4. 类变量内存布局
从图中可以直观感受:两个对象共享的一个数据,存放count的这个空间是个堆空间。
静态变量是被所有对象实例共享的
在JDK 8之前,这个count静态变量是在方法区里的静态域,JDK 8或者之后,是放在堆里面的,通过反射机制,会加载一个class对象。
当类进行加载的时候,会在堆生成的class对象,通过这个对象可以拿到很多类的信息。
也就是说在JDK 8以后,通常的认为静态变量在堆里面的这个类对应的Class对象的最后。
在面试的时候说清楚这一点就行了。不管是在堆还是静态域,这里不会影响我们对静态变量的使用。
静态变量的核心是:1.被所有对象共享的。2.在类加载的时候就生成。
5. 什么是类变量
6. 如何定义类变量
7. 如何访问类变量
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";
}
8. 类变量使用注意事项和细节讨论
9. 类方法基本介绍
11. 类方法应用案例
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);
}
}
12. 类方法经典的使用场景
也就是说我们不用创建一个对象,就能使用其中的方法
//如果我们希望不创建实例,也可以调用某个方法(即当做工具来使用)
//这时,把方法做成静态方法时非常合适
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
}
13. 类方法使用注意事项和细节讨论
14. 练习题
因为是后++,那么就是先输出一个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;