1.静态是什么?有什么用?

static的主要作用在于创建独立于具体对象的域变量或者方法。

每创建一个对象,都会在堆里开辟内存,存成员(属性),但是不存方法,方法是共用的,没必要每一个对象都浪费内存去存方法。有一个叫方法区的地方,专门存方法。方法区里又有静态域,存静态变量或者静态方法。

普通变量和方法的调用:通过对象调用

静态变量和方法的调用:通过对象或类调用

public class MyTest8 {
public static void main(String[] args) {
System.out.println(Plant.name);//通过类调用
Plant p1=new Plant();
System.out.println(p1.name);//通过对象调用
p1.name="植物";//类似方法,是公用的,改了之后就是改了,新建对象也是这个值
Plant p2=new Plant();
System.out.println(p2.name);//通过对象调用
}
} class Plant{
static String name="静态植物";
public static void say() {
System.out.println("植物类");
}
}
/**输出
静态植物
静态植物
植物
*/

静态的调用

在类被加载的时候,静态的代码都会被加载,并且只加载一次,放在方法区里,该类的对象一起用。省时省力。

2.加载类有什么用?

任何程序都要先加载到内存中才能和CPU进行交流,而JVM中的ClassLoader(类加载器)就是负责提前将,class文件加载到内存中去的。

3.类何时被加载?(普通人的宏观理解)

  • 实例化对象时,如Chinese c1=new Chinese();此时加载了Chinese类
  • 通过类名调用静态变量或静态方法的时候
  • 如果实例化子类对象,会先加载父类

通过代码验证:

public class MyTest8 {

    public static void main(String[] args) {
Plant.say();//通过类名调用静态方法
Plant p1 = new Plant();//创建对象
Plant p2 = new Plant();
}
} class Plant{
static String name="静态植物";
public static void say() {
System.out.println("植物类");
}
static {
System.out.println("植物类的静态代码被执行加载了");
}
{
System.out.println("植物类的普通代码被加载了");
}
}

输出:

植物类的静态代码被执行加载了
植物类
植物类的普通代码被加载了
植物类的普通代码被加载了

由此可知,Plant.say();调用方法时就加载了类,静态代码也都被执行了,并且只执行一次,创建对象的时候再次加载类,但是不执行静态代码,而是非静态代码。

再通过继承关系观察静态和非静态的关系

public class MyTest8 {

    public static void main(String[] args) {
Flower.say();//通过类名调用静态方法
Flower f1=new Flower();//创建花类对象
Flower f2=new Flower();
}
} class Plant{
static String name="静态植物";
public static void say() {
System.out.println("植物类");
}
static {
System.out.println("植物类的静态代码被执行加载了");
}
{
System.out.println("植物类的普通代码被加载了");
}
} class Flower extends Plant{
static {
System.out.println("花类被加载了");
} static String name="花";
public static void say() {
System.out.println("花类");
}
{
System.out.println("花类的普通代码被加载了");
}
}

输出:

植物类的静态代码被执行加载了
花类被加载了
花类
植物类的普通代码被加载了
花类的普通代码被加载了
植物类的普通代码被加载了
花类的普通代码被加载了

由此可知:调用静态的东西,只执行静态的代码,静态代码只执行一次。创建对象的时候也会加载,如果静态没有被加载过也会被加载,加载过就不用。加载子类的时候,会先把父类加载一次。

在代码中,调用子类静态方法,则先加载父类的静态代码,再加载子类的静态代码,再调用方法。创建对象的时候,先加载父类,再加载子类。

类装载的过程:

  • 加载:根据查找路径找到相应的 class 文件然后导入;
  • 检查:检查加载的 class 文件的正确性;
  • 准备:给类中的静态变量分配内存空间;
  • 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
  • 初始化:对静态变量和静态代码块执行初始化工作。

牛客刷题

1.初始化代码执行顺序是:父类静态→子类静态→父类普通代码块→子类普通代码块→父类构造方法→子类构造方法

2.静态方法属于类不属于对象;静态方法中只能访问其他静态方法和静态数据,不能访问非静态的。

3.静态不可用this调用。

最新文章

  1. oracle 学习笔记(四)
  2. soui使用wke时,设置js回调注意事项
  3. Oracle基本教程
  4. Flex数据绑定陷阱(一)
  5. rsync+inotify实现实时同步案例--转
  6. LPC43XX JTAG Scan Chain
  7. 论Visual Studio和.NET Framework
  8. topcoder 594 DIV2 foxandclassroom
  9. Android入门:绑定本地服务
  10. linux 正则表达式深度解析
  11. Sphnix创建文档
  12. 自定义 Layer 属性的动画
  13. UESTC_方老师的分身 II CDOJ 915
  14. 剑指offer-面试题15.链表中倒数第k个结点
  15. 让互联网更快,Server Push 特性及开启方式详解
  16. uboot使用笔记
  17. conda添加多个版本的python
  18. 汽车控制器LIMPHOME电路设计
  19. css和javascript代码写在页面中的位置说明
  20. Python3之弹性力学——应力张量2

热门文章

  1. mysql数据库备份工具xtrabackup
  2. APP 链接ROS时出现pymongo.errors.ServerSelectionTimeoutError: localhost:27017 错误
  3. oracle数据库安装过程中的疑惑—该记录是本人以前写在微博上的文章
  4. vue + element 文件上传 并将文件转 base64
  5. 全链路追踪技术选型:pinpoint vs skywalking
  6. 基于word2vec的文档向量模型的应用
  7. 【生活现场】从打牌到map-reduce工作原理解析(转)
  8. Git更改文件名大小写,提交失败问题解决
  9. [转] JavaScript数组去重(12种方法)
  10. JavaScaript学习笔记第(一)