)
目录1.static关键字1.1static修饰成员变量1.1static修饰成员方法1.3被static修饰的成员的访问2.代码块的分类2.1普通代码块2.2构造代码块2.3静态代码块前言接着上回我们学习的类和对象二今天我们继续学习有关类相关的知识。static 关键字是 Java 中非常重要的修饰符它能让成员变量、成员方法脱离对象而依附于类本身实现数据共享与工具方法的封装而不同类型的代码块则控制着类与对象初始化的时机与顺序是理解类加载机制的关键。通过本次学习你将能更灵活地设计类的结构编写出更高效、更规范的 Java 代码。1. .static关键字被static修饰的成员变量就已经不属于具体的对象的成员变量了。以我们上学时候的班级来举例每个人都不一样但是班级里面的同学都属于同一个班级的班级被每一个同学共有。而被static修饰的成员变量我们称之为静态成员变量与我们非静态成员变量有所不同被static修饰的成员变量和成员方法在进行初始化的时候也会有顺序差别。 返回目录1. 1static修饰成员变量首先我们创建一个Dog的类然后让名字被static修饰。然后我们会发现我们用this这个关键字的时候想要输出Dog这个类的名字的时候发现根本就点不出来。但是当我们自己手写上去的时候又发现编译器没有报错只有黄色的警告。我们这么写的时候不合理但是合法不建议这么写但是我们想要正确去访问static修饰的成员变量的时候该怎么做呢publicclassDog{staticStringname;publicvoidprint(){System.out.println(Dog.name);}}我们使用类名去访问的时候编译器就会给我们弹出来name这个被static修饰的成员变量。结论当我们使用类名去访问成员变量的时候编译器不会发生报错既合法又合理被static修饰的成员变量不属于某一个对象所有对象共用一个成员变量。被static修饰的成员变量存储的地方不是我们的堆区而是我们的方法区内。生命周期也就是我们定义的类的开始到类结束。publicclassDog{//生命周期的开始staticStringname;publicvoidprint(){System.out.println(Dog.name);}}//生命周期结束 返回目录1. 2static修饰成员方法被static修饰的成员方法和被static修饰的成员变量相似的。被static修饰的成员方法已经不是某个具体的对象所拥有的而是被每个成员变量共有。publicclassDog{publicStringname;publicvoidprint(){System.out.println(this.name);}staticvoidcall(){//被static修饰的成员方法System.out.println(正在汪汪叫);}}当我们使用创建的对象去调用的时候我们发现和static修饰的成员变量一样都是写出第一个首字母却点不出来call这个方法。我们自己强制写出被static修饰的方法名字的时候编译器不会报错这种写法合法但是不合理不推荐大家使用这种方法访问被static修饰的成员方法。正确的访问方式使用类名去进行访问我们就能够点出被static修饰的成员方法。当我们使用我们static修饰的成员方法去访问我们没有被static修饰的成员方法的时候publicclassDog{publicStringname;publicvoidprint(){System.out.println(this.name);}staticvoidcall(){System.out.println(正在汪汪叫);}staticvoideat(){// System.out.println(this.name正在吃饭...);}}我们发现编译器给我们报错了。那我们非静态成员方法去访问静态成员方法呢我们发现编译器没有发生报错。结论被static修饰的成员方法是静态成员方法。当我们使用静态成员方法去调用访问非静态成员方法的时候编译器会报错。静态成员方法不能访问非静态成员变量非静态成员方法内部能访问调用静态成员变量。被static修饰的成员变量不能通过this关键字来调用。 返回目录1. 3被static修饰的成员的访问总结我们static修饰的成员变量和成员方法访问方式通过类名来调用静态成员变量或者成员方法不建议通过对象来进行调用因为不合理静态成员方法不能调用非静态成员变量。而非静态的成员方法能调用静态成员变量。调用方式的举例publicclassDog{staticStringname;publicvoidcall(){Systemout.println(Dog.name正在汪汪叫);//非静态成员方法访问静态成员方法}publicvoideat1(){System.out.println(Dog.name正在吃饭...);//静态成员方法访问静态成员变量。}} 返回目录2.代码块的分类什么是代码块代码块{ }被花括号括起来的就是代码块。主要用途主要用来初始化我们的实例化对象。包括被static修饰的成员变量分类普通代码块主要定义在方法的{ }花括号内部的当我们可以用这个代码块来初始化实例化的对象。一般不用普通代码开来初始化实例化对象构造代码块定义在类中却不加任何修饰{ } 有些书中又叫实例代码块。主要用来初始化实例成员变量。静态代码块主要形式static{ } 主要用途初始化实例化成员变量。同步代码块我们在学习类和对象的时候暂时用不到这个代码块。 返回目录2. 1普通代码块定义定义在方法内部。publicclassTest1{publicstaticvoidmain(String[]args){{inta10;}inta20;}}通常我们不使用这样的写法。 返回目录2. 2构造代码块构造代码块也叫实例代码块。主要用途给我们成员变量进行初始化。例如;publicclassDog1{publicStringname;intage;{this.name旺财;this.age2;}}我们在上一节的时候知道我们在没有写不带参数的构造方法的时候编译器会默认给我们生成一个我们看不见的构造方法。那我们的构造方法和这个普通代码块谁先调用或者我们在写普通代码块初始化的时候不带参数的构造方法会不会被调用?publicclassDog1{publicStringname;intage;{name旺财;age2;}publicDog1(){this.age3;this.name小黑;System.out.println(构造方法被调用...);}}publicclassDog1{publicStringname;intage;publicDog1(){this.age3;this.name小黑;System.out.println(构造方法被调用...);}{this.name旺财;this.age2;}}我们知道实例代码块先被执行后执行构造代码块。publicclassDog1{publicStringname旺财;intage2;publicDog1(){this.age3;this.name小黑;System.out.println(构造方法被调用...);}}和就地初始化相比构造方法后调用。publicclassDog1{publicStringname小黑;intage3;{this.name旺财;this.age2;}}publicclassDog1{{this.name旺财;this.age2;}publicStringname小黑;intage3;}和就地初始化相比谁先写谁先被执行。执行顺序就地初始化构造代码块不带参数的构造方法。 返回目录2. 3静态代码块静态代码块被static修饰的{ }主要用途初始化静态成员变量。静态代码块会被执行几次publicclassDog1{privateStringname;privateintage;{System.out.println(实例代码块被执行);}static{System.out.println(静态代码块被执行);}}publicclassTest1{publicstaticvoidmain(String[]args){Dog1dog1newDog1();System.out.println();Dog1dog2newDog1();}}我们发现静态代码块只被执行了一次。他们的执行顺序比较publicclassDog1{privateStringname;privateintage;{System.out.println(实例代码块被执行);}static{System.out.println(静态代码块被执行);}}我们发现静态代码块先被执行。总结不管我们生成多少个对象静态代码块只会被执行一次。静态成员变量是类的属性是在JVM加载类的时候开辟并初始化的。编译器会按照先后顺序执行各个代码块。静态实例构造注意实例代码块只有在创建对象时才会执行。 返回目录