赞
踩
这是JAVA基础面向对象的第二部分。第一部分是JAVA基础面向对象(1)。建议大家先看JAVA基础面向对象(1),有助于更好的理解这次的知识内容哦。
Student类代码
- package Mianxiangduixiangshang;
-
- public class Student06 {
- public Student06() {
- System.out.println("无参的构造方法");
- }
- public Student06(String name) {
- this();
- System.out.println("一个参数的构造方法");
- }
- public Student06(String name, int age) {
- this(name);
- System.out.println("两个参数的构造方法");
- }
- }
Example06类代码
- package Mianxiangduixiangshang;
-
- public class Example06 {
- public static void main(String[] args) {
- Student06 s1 = new Student06("Jack", 22);
- }
- }
运行结果
案例总结
1.从运行结果可以看出,三个构造方法都被调用了,为了更加清楚地了解三个构造方法的执行顺序,下面通过一张图例进行说明。
2.在构造方法中,使用 this调用重载构造方法的代码必须放在第一行,否则程序不能通过编译,这就限定了在一个构造方法中只能调用一次重载的构造方法。
3.在构造方法中可以通过this.方法名([参数 …])的方式调用普通的成员方法,但是在普通的成员方法中不能使用this([参数 …])的方式来调用构造方法。
Student类代码
- package Mianxiangduixiangshang;
-
- public class Student07 {
- public void finalize() {
- System.out.println("垃圾对象被回收了");
- }
- }
Example07类代码
- package Mianxiangduixiangshang;
-
- public class Example07 {
- public static void main(String[] args) {
- new Student07();
- new Student07();
- System.gc();
- for (int i = 0; i < 100000000; i++) {
- // 延长程序结束时间
- }
- }
- }
运行结果
案例总结
1、从运行结果可以看到,两个Student对象的finalize()方法都被调用了,这表示两个对象作为垃圾被回收了。如果把System.gc()这行代码注释,会发现命令行窗口不会打印任何内容,这说明对象在变成垃圾后不会被立即回收,同时也验证了System.gc()方法的作用。
2、由于System.gc()方法只是通知Java虚拟机尽快进行垃圾回收,这意味着垃圾回收器也可能不会马上运行,因此,在程序的最后使用了一个for循环来延长程序运行的时间,从而确保能够看到垃圾对象被回收的过程。
3、Student类中定义的 finalize()方法其签名必须是public(protected) void finalize()[throw Throwable]{},这样做的原因会涉及到后面的一些知识,比如类的继承、Object类、方法的重写、异常等等,同学们在学完这些内容后就会明白其中的道理。
为了更好地理解Student类中静态变量className和Student实例对象的关系,下面通过一个图例进行演示。
Student类代码
- package Mianxiangduixiangshang;
-
- public class Student08 {
- String name;
- static String className;
- }
Example08类代码
- package Mianxiangduixiangshang;
-
- public class Example08 {
- public static void main(String[] args) {
- Student08.className = "三年级二班";
- Student08 s1 = new Student08();
- s1.name = "张三";
-
- Student08 s2 = new Student08();
- s2.name = "李四";
-
- Student08 s3 = new Student08();
- s3.name = "王五";
-
- System.out.println("我的名字是" + s1.name + ",来自" + s1.className);
- System.out.println("我的名字是" + s2.name + ",来自" + s2.className);
- System.out.println("我的名字是" + s3.name + ",来自" + s3.className);
- }
- }
运行结果
案例总结
1、本案例中,三个Student对象的className属性值均为“三年级二班”,对于这样的相同数据,没有必要在每个对象中都开辟一块空间存储,完全可以在内存中只用一块空间存储,并被一个类的所有实例对象所共享。在Java中提供了一个static关键字,使用static关键字修饰的成员变量称为静态变量,静态变量能被该类所有实例对象共享。
2、静态变量可以使用“类名.静态方法名”的方式访问,也可以通过“对象引用变量.静态方法名”的方式访问,例如本例中的静态变量className,通过Student.className或者s2.className这两种方式访问都是可以的,不过更推荐使用前一种方式。
代码
- public class Example10{
- static void staticMethod1() {
- System.out.println("静态方法1");
- // nonStaticMethod1();
- }
- static void staticMethod2() {
- System.out.println("静态方法2");
- }
- void nonStaticMethod1() {
- System.out.println("非静态方法1");
- staticMethod1();
- nonStaticMethod2();
- }
- void nonStaticMethod2() {
- System.out.println("非静态方法2");
- }
- public static void main(String[] args) {
- Example10 e = new Example10();
- e.nonStaticMethod1 ();
- }
- }
运行结果
1、在静态方法中只能访问静态方法,在非静态方法中可以访问静态方法和非静态方法。
2、思考一下:在静态方法中是否能够访问静态变量和非静态变量?其实和上面的讲解一样,非静态变量只能通过对象或者对象的引用变量访问,而静态方法在创建对象之前就可以通过类名直接访问,因此在静态方法中不能访问非静态变量,只能访问静态变量。
编写Example11类,在类中定义一个静态代码块、一个构造代码块、一个无参的构造方法和一个成员方法localBlock(),在localBlock()方法中定义一个局部代码块。
创建Example11类的两个实例对象,使用Example11类型的变量e1和e2引用,并通过变量e1和e2调用这两个对象的localBlock()方法。
Example11类代码
- package Mianxiangduixiangshang;
-
- public class Example11 {
- static {
- System.out.println("静态代码块");
- }
- {
- System.out.println("构造代码块");
- }
- public Example11() {
- System.out.println("构造方法");
- }
- void localBlock() {
- {
- System.out.println("局部代码块");
- }
- }
- public static void main(String[] args) {
- Example11 e1 = new Example11();
- e1.localBlock();
- System.out.println("-----------------");
- Example11 e2 = new Example11();
- e2.localBlock();
- }
- }
运行结果
1、静态代码块在加载类的时候执行,由于类只在第一次使用时被加载,且只加载一次,因此静态代码块只执行一次。从运行结果可以看到,虽然创建了两个Example11的实例对象,由于Example11类只会加载一次,所以“静态代码块”只打印一次。
在实际开发中,经常有一些代码需要在类加载时就执行,比如加载数据库驱动,这些代码就应该放在静态代码块中。
2、构造代码块在创建类的实例对象时执行,也就是说每次创建类的实例对象时,都会执行一次构造代码块。从运行结果可以看到,构造代码块优先于构造方法执行,因此在实际开发中,可以把重载构造方法中重复的代码抽取到构造代码块中执行。
3、局部代码块定义在方法中,它在方法被调用的时候执行。使用局部代码块是为了限制变量的生命周期,使变量在使用完毕后被尽快回收,从而节省内存空间。
JAVA基础 面向对象(2)也整理完成。明天继续JAVA基础 面向对象(3)。这部分属于是基础中的难点,建议点赞收藏哦。我也有些东西没记住,还要多多重复看笔记加深自己的印象。今天就总结到这里,希望能够对你有所帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。