Java学习笔记(八)——类变量和类方法
前言
该部分已经进入面向对象高级部分知识,主要涉及到类变量、类方法、代码块等知识
类变量
引出
例子:有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少小孩在玩?
思路:
- 1、在main方法中定义一个变量count
- 2、当一个小孩加入游戏后,count++,最后count就记录有多少个小孩玩游戏
问题:
- 1、count是一个独立于对象/类的变量
- 2、以后访问count比较麻烦,没有使用opp
解决:
- 如果设计一个int count表示总人数,我们在创建一个小孩时,就把count+1,并且count是所有对象共享的就ok了
因此我们引出类变量(也叫静态变量)
类变量快速入门
1 | class child{ |
类变量基础知识
什么是类变量
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问他时,取到的都是相同的值,同样任何一个类的对象去修改它时,修改的也是同一个变量。
如何定义类变量
定义语法:
- 访问修饰符 static 数据类型 变量名;【推荐】
- static 访问修饰符 数据类型 变量名;
如何访问类变量
类名.类变量名【推荐】
对象名.类变量名【静态变量的访问修饰符的访问权限和范围和普通属性是一样的】
类变量内存布局
静态变量究竟放在哪里?
说法很多:
- 1、静态域(方法区)
以上述例子为例:
由于count是属于静态变量的,而child在进行类加载的时候,其类信息会放在方法区里面。在方法区中有一个空间叫静态域,这个count也就是在这个方法区的静态域中。
- 2、堆
以上述例子为例:
放在堆中Child类对应的class对象最后。那这个class对象是什么呢?
当Child这个类在进行加载的时候,它会在堆里面生成一个Child类对应的class对象,这个class对象是一个原型对象,在创建每一个对象实例的时候都会依照它来创建,而且我们通过这个class对象可以拿到很多类的信息,这个在反射里面会详细讲。
Class对象如同堆中其他对象一样,存在于GC堆中。
那么到底放在哪个地方呢?——看jdk版本
- JDK7、JDK8以前它们是放在方法区的静态域中。
- JDK8之后:其实是放在堆中类对应的Class对象最后。会通过反射机制加载一个Class对象,在这个Class实例的尾部,它会把静态的数据放在Class对象中。
但不论是放在堆里面还是方法区的静态域中,都不会影响两个事实:
- static变量是被同一个类所有对象共享的,因此不影响对静态变量的使用
- static类变量,在类加载的时候就被生成了。——这就意味着即使没有创建对象实例也可以访问
类方法
基本介绍
类方法也叫静态方法,形式如下:
- 访问修饰符 static 数据返回类型 方法名( ){ }
- static 访问修饰符 数据返回类型 方法名( ){ }
类方法的调用:
- 类名.类方法名
- 对象.类方法名
经典使用场景
当方法中不涉及到任何和对象相关的成员,则可以将方法设计为静态方法,提高开发效率
比如:工具类中的方法。Math类、Arrays类、Collections集合类
程序员实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用,比如打印以为数组,冒泡排序,完成某个计算任务等。
使用细节、注意事项
1、类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区。类方法中无this的参数,普通方法中隐含着this的参数。
2、普通方法和对象有关,需要通过对象名调用,不能通过类名调用,而静态方法可以。
3、类方法中不允许使用和对象有关的关键字,比如this和super,普通方法可以。
4、类方法中只能访问静态变量或者静态方法。
5、普通成员方法,既可以访问非静态成员,也可以访问静态成员。
深入理解Main方法
语法说明:
main方法形式:
1 | public static void main(String[] args){ |
- 1、main方法是JVM调用的
- 2、Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
- 3、Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static
- 4、该方法接受String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数
String[] args这个字符串数组里面的形参到底是什么时候传进去的?是在执行下面程序(第5点)的时候传入的:
- 5、Java执行的程序 参数1 参数2 参数3
1 | public class Test{ |
我们都知道,编写了上述代码后,需要:
1 | javac Hello.java |
才可以执行,这个时候我们可以看到终端输出为空,但是如果将运行代码修改成下面:
1 | java Hello tom jack smith |
我们就可以看到输出:
1 | 第1个参数=tom |
特别说明:
- 1、在main()方法中,我们可以调用main方法所在类的静态方法或静态属性
- 2、但是,不能直接访问该类中的非静态成员,必须创建一个实例对象后,才能通过这个对象去访问类中的非静态成员。