JAVA基础 面向对象(2)

文章目录

  • 前言
  • this关键字访问构造方法
  • 七、垃圾回收机制
  • 八、静态变量
  • 九、静态方法中访问类的成员
  • 十、代码块
  • 总结


前言

这是JAVA基础面向对象的第二部分。第一部分是JAVA基础面向对象(1)。建议大家先看JAVA基础面向对象(1),有助于更好的理解这次的知识内容哦。


六、this关键字访问构造方法

案例描述

  1. 练习目标
    1. 掌握如何在构造方法中使用this关键字访问重载的构造方法
  2. 需求分析
    1. 如果一个类中定义了多个重载的构造方法,为了避免在重载的构造方法中重复书写代码,可以在一个构造方法中使用this关键字调用其它的构造方法。为了让初学者掌握this关键字访问构造方法的用法,本案例将演示如何使用this关键字调用其他的构造方法。
  3. 设计思路(实现原理)
    1. ​​​​​​​在Student类中创建多个重载的构造方法,包括无参的构造方法和一个参数的构造方法,以及两个参数的构造方法。
    2. 在一个参数的构造方法中使用this关键字调用无参构造方法,在两个参数的构造方法中调用一个参数的构造方法。
    3. 编写测试类Example06,在main()方法中,调用两个参数的构造方法创建对象,演示构造方法的执行顺序。

        案例实现

                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([参数 …])的方式来调用构造方法。

七、垃圾回收机制

案例描述

  1. 练习目标
    1. 掌握垃圾回收机制的特点
    2. 掌握垃圾回收相关的方法
  2. 需求分析
    1. ​​​​​​​垃圾对象会占用一定的内存空间,当垃圾对象积累到一定程度后,Java虚拟机会自动进行垃圾回收。但是,如果希望程序可以及时通知Java虚拟机回收垃圾对象,可以通过System.gc()方法强制启动垃圾回收器回收垃圾。为了让初学者熟悉垃圾回收机制,本案例将演示如何通过System.gc()方法强制启动垃圾回收器回收垃圾。
  3. 设计思路(实现原理)
    1. 对Student类进行修改,在类中对finalize()方法进行重写。
    2. 编写测试类Example07,创建若干个Student对象,然后调用System.gc()方法通知垃圾回收期回收垃圾,为了确保可以看到垃圾回收的过程,可以在类中编写一个简单的循环语句,延长程序执行时间。

        案例实现

                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类、方法的重写、异常等等,同学们在学完这些内容后就会明白其中的道理。

八、静态变量

案例描述

  1. 练习目标
    1. 了解静态变量的作用
    2. 掌握静态变量的定义和使用方式
  2. 需求分析
    1. 当多个对象存储的数据相同时,可以使用静态变量的方式存储。例如,有一个Student类具有name、className属性,请根据该类创建出三个Student对象,并将这些对象的className值都设置为“三年级二班”。
  3. 设计思路(实现原理)
    1. 定义Student类,并在类中定义name和className属性。
    2. 编写测试类Example08,在main()方法中创建三个学生对象,并分别为这些对象的name和className属性赋值,然后输出这些对象的name和className值。
    3. 对Student类进行修改,将className定义为静态变量。
    4. 修改测试类,在main()方法中使用Student.className = “三年级二班”语句为静态变量className进行赋值,然后输出这些对象的name和className值。
    5. 为了更好地理解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这两种方式访问都是可以的,不过更推荐使用前一种方式。

九、静态方法中访问类的成员

案例描述

  1. 练习目标
    1. 了解在静态方法中只能访问类的静态成员,而不能访问非静态成员。
  2. 需求分析
    1. ​​​​​​​在程序中经常会调用方法,但静态方法之间、静态方法和非静态方法之间,它们是否能够互相调用呢?请编写一个测试类,在类中定义若干个静态方法和非静态方法,通过方法之间的相互调用,演示静态方法和非静态方法的调用情况。   
  3. 设计思路(实现原理)
    1. 编写Example10类,在类中定义两个静态方法staticMethod1()、staticMethod2(),两个非静态方法nonStaticMethod1()、nonStaticMethod2()
    2. 在Example10类中,针对定义的四个方法进行互相调用,观察调用情况。

        案例实现

                代码

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、思考一下:在静态方法中是否能够访问静态变量和非静态变量?其实和上面的讲解一样,非静态变量只能通过对象或者对象的引用变量访问,而静态方法在创建对象之前就可以通过类名直接访问,因此在静态方法中不能访问非静态变量,只能访问静态变量。

十、代码块

案例描述

  1. 练习目标
    1. 理解代码块的不同分类
    2. 掌握不同代码块的作用及其执行时机
  2. 需求分析
    1. ​​​​​​​有时候,需要将某一段关联紧密的或者实现了某一功能的代码封装的一个代码块中。为了让初学者熟悉代码块的应用,本案例将编写一个包含了静态代码块,局部代码块和构造代码块的类,演示不同代码块之间的执行时机。   
  3. 设计思路(实现原理)
    1. 编写Example11类,在类中定义一个静态代码块、一个构造代码块、一个无参的构造方法和一个成员方法localBlock(),在localBlock()方法中定义一个局部代码块。

    2. 创建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)。这部分属于是基础中的难点,建议点赞收藏哦。我也有些东西没记住,还要多多重复看笔记加深自己的印象。今天就总结到这里,希望能够对你有所帮助。

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心态还需努力呀

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值