【Java基础教程】(十)面向对象篇 · 第四讲:解析Java中的this关键字,引用传递印象加强:理解与实践~

news2024/10/7 4:27:33

Java基础教程之面向对象 · 第四讲

  • 本节学习目标
  • 1️⃣ this 关键字
    • 1.1 调用本类属性
    • 1.2 调用本类方法
    • 1.3 表示当前对象
  • 2️⃣ 引用传递
    • 2.1 基本概念
    • 2.2 实际应用
  • 🌾 总结

在这里插入图片描述

本节学习目标

  • 掌握关键字this的特征以及使用;
  • 掌握引用传递分析思维;

1️⃣ this 关键字

在Java中,关键字 this 可能是最复杂的一个,但几乎所有的代码开发都离不开它。在Java中,this 可以用于完成以下三件事情:调用本类属性,调用本类方法以及表示当前对象。下面将详细讲解这三种应用场景。

1.1 调用本类属性

在一个类的定义的方法中可以直接访问类中的属性,但是很多时候有可能会出现方法参数名称与属性名称重复的情况,所以此时就需要利用 “this.属性” 的形式明确地指明要调用的是类中的属性而不是方法的参数,下面通过代码来验证这一问题。

//	范例 1: 观察程序问题
class Book {
	private String title;
	private double price;
	
	public Book(String title, double price){
		title = title;	//原本的目的是希望将构造方法中的title变量内容设置给title 属性
		price = price;	//原本的目的是希望将构造方法中的 price变量内容设置给price属性
	}
	 
	// setter、getter略
	public String getInfo(){
		return "书名:"+ title +",价格:"+ price;
	}
}
public class TestDemo {
	public static void main(String args[]){
		Book book = new Book("Java 开发", 89.2);
		System.out.println(book.getInfo());
	}
}

程序执行结果:

书名:null,价格:0.0

此程序在Book 类中直接定义了一个构造方法,其目的是希望通过构造方法为 titleprice 两个属性进行赋值,但最终的结果发现并没有成功赋值,这是因为在 Java 中的变量使用具备 “就近取用”的原则,在构造方法中已经存在 titleprice 变量名称,所以如果直接调用 titleprice 变量将不会使用类中的属性,只会使用方法中的参数(如下图所示),所以此时 Book 类的构造方法是无法为 titleprice属性赋值的。

在这里插入图片描述
在这种情况下为了可以明确地找到要访问的变量(属于类中的属性),需要在变量前加上 this, 这样就可以准确地进行属性的标记。

需要注意的是,在访问类属性时一定要加上关键字"this"。在编写代码时,一些朋友主要关注实现代码功能,而忽视了良好的编程习惯。在这里,需要提醒大家的是,为了避免不必要的麻烦,在类中访问属性时无论是否有重名变量,都应该使用关键字"this"来明确指定。

//	范例 2: 使用 this 关键字明确地表示访问类中的属性
class Book {
	private String title;
	private double price;
	
	public Book(String title, double price){
		this.title = title;  	//this.属性表示的是本类属性,这样即使与方法中的参数重名也可以明确定位 
		this.price = price;		//this.属性表示的是本类属性,这样即使与方法中的参数重名也可以明确定位
	}
	// setter、getter 略
	public String getInfo(){
		return "书名:" + title + ",价格:" + price;
	}
}
public class TestDemo{
	public static void main(String args[]){
		Book book = new Book("Java 开发",89.2);
		System.out.println(book.getInfo());
	}
}

程序执行结果:

书名:Java 开发,价格:89.2

本程序由于构造方法中访问属性时增加了 this 关键字,所以可以在变量名称相同的情况下,明确地区分属性或参数,传递的内容也可以正常赋值。

1.2 调用本类方法

通过上边的讲解,大家应该清楚了 this 本质上指的就是明确进行本类结构的标记,而除了访问类中的属性外,也可以进行类中方法的调用。
在一个类中,通过this调用本类方法分为以下两种形式。

  • 调用本类普通方法:如果要调用本类方法,则可以使用 “this. 方法()”调用;
  • 调用本类构造方法:在一个构造中要调用其他构造,可以使用 “this()” 调用。
//	范例 3: 调用本类普通方法
class  Book{
	private String title;
	private double price;
	
	public Book(String title, double price){
		this.title = title:
		this.price = price;
	}
	
	public void print(){
		System.out.println("更多文章请访问:https://blog.csdn.net/LVSONGTAO1225");
	}
	// setter、getter 略

	public String getInfo(){
		this.print(); 	//调用本类方法
		return "书名:"+title+",价格:"+price;
	}
}
public class TestDemo {
	public static void main(String args[]){
		Book book =new Book("Java 开发",89.2);
		System.out.println(book.getlnfo());
	}
}

程序执行结果:

更多文章请访问:https://blog.csdn.net/LVSONGTAO1225
书名:Java开发,价格:89.2

此程序在 getlnfo() 方法执行时,进行对象信息取得前,调用了本类中定义的 print() 方法,由于是在本类定义的,所以可以直接利用 “this.方法()” 的形式进行访问。

从代码的严格角度来讲,利用“this.方法()”调用本类中其他普通方法的做法是非常标准的,由于是在一个类中,也可以直接使用“方法()”的形式调用。但是从代码标准的角度来说都会使用 this 调用本类属性或本类方法。

除了可以调用本类普通方法,在一个类中也可以利用 “this()” 的形式实现一个类中多个构造方法的互相调用。例如:一个类中存在3个构造方法 (无参,有一个参数,有两个参数), 但是不管使用何种构造方法,都要求在实例化对象产生的时候输出一行提示信息:“一个新 Book 类对象产生了”,则按照前面学习到的知识,可以编写如下代码来实现。

//	范例 4: 观察程序问题
class Book {
	private String title;
	private double price;
	
	public Book(){
		System.out.println("一个新 Book 类对象产生了");
	}
	public Book(String title){
		System.out.println("一个新 Book 类对象产生了");
		this.title = title;
	)
	public Book(String title, double price){
		System.out.println("一个新 Book 类对象产生了");
		this.title = title;
		this.price = price;
	}
	
	// setter、getter 略
	public String getInfo(){
		return "书名:"+this.title+",价格:"+this.price;
	}
}
public class TestDemo{
	public static void main(String args[]){
		Book book = new Book("Java 开发",89.2);
		System.out.println(book.getInfo());
	}
}

程序执行结果:

一个新 Book 类对象产生了
书名:Java 开发,价格:89.2

此程序定义了3个构造方法,并且每一个构造方法都会打印相应的信息提示。此时,不管调用哪一个构造方法,都可以完成指定的信息输出。可以发现,如果假设将这一行输出的代码想象为50行代码量,那么这个程序中会出现大量的重复代码,而程序的设计目标是减少重复代码,那么此时就可以利用 this()来避免重复代码。

//	范例 5: 消除构造方法中的重复代码
class Book{
	private String title;
	private double price;
	
	public Book(){
		System.out.println("一个新 Book 类对象产生了");	//把这行语句想象成50行代码
	}
	public Book(String title){
		this();			//调用本类无参构造方法
		this.title = title;
	}
	public Book(String title, double price)(
		this(title);	//调用本类有一个参数的构造方法
		this.price = price;
	}

	// setter、getter 略
	public String getInfo(){
		return "书名:"+this.title+",价格:"+this.price;
	}
}

public class TestDemo {
	public static void main(String args[]){
		Book book = new Book("Java开发",89.2);
		System.out.println(book.getInfo());
	}
}

程序执行结果:

一个新 Book 类对象产生了
名:Java开发,价格:89.2

此程序在两个参数的构造方法中(“public Book(String title, double price)”)使用 “this(title)” 调用了有一个参数的构造方法(“public Book(String title)”), 而在一个参数的构造中调用了无参构造,这样不管调用哪个构造,都会执行特定功能(案例为输出操作)。

但需要注意的是,在使用 this 调用构造方法时,存在两个重要的限制(会在程序编译时检查出来):

  • 使用"this()" 调用构造方法形式的代码只能够放在构造方法的首行;
  • 进行构造方法互相调用时,一定要保留调用的出口。

对于第一点限制比较好理解,因为构造方法是在类对象实例化时调用的,所以构造方法间的互相调用,就只能放在构造方法中编写。如果我们将 “this()” 调用放置在构造方法的非首行位置,那么在该语句之前已经有一些初始化操作被执行了。这就会导致调用的构造方法中的初始化操作无法准确地进行,从而产生错误或不符合预期的结果。

因此,为了确保对象的正确初始化顺序和避免出现意外的问题,使用 "this()"调用构造方法的代码必须放在构造方法的首行。这样可以保证先执行其他构造方法进行必要的初始化,然后再继续执行该构造方法中的特定初始化操作,确保对象状态的正确性。

进行构造方法互相调用时,一定要保留调用的出口是为了确保程序的逻辑正确性和避免可能的死循环。

当一个构造方法调用另一个构造方法时,实际上是在进行对象的初始化过程。这种调用可以使代码更加简洁和灵活,方便我们根据需要选择不同的构造方法来进行对象初始化。

然而,如果我们不小心将调用的出口删除或忽略,就会导致构造方法间的无限循环调用(也称为递归调用),从而导致程序进入无限循环并最终导致堆栈溢出错误。

通过保留构造方法调用的出口,即使用关键字"this()"来明确指示调用其他构造方法,我们可以确保每个构造方法都有明确定义的结束点,从而防止无限循环的发生。

下面通过代码来验证,辅助理解第二个限制。

//	范例 6: 观察错误的代码
class Book {
	private String title
	private double price;
	
	public Book(){
		this("HELLO",1.1);                         //调用双参构造
		System.out.println("一个新的Book类对象产生。");
	}
	public Book(String title){
		this();
		this.title = title;
	}
	public Book(String title, double price){
		this(title);                               //调用本类的单参构造
		this.price = price;
	}
	
	// setter、getter略
	public String getInfo(){
		return "书名:"+this.title+",价格:"+this.price;
	}
}

此时调用的语句的确是满足了需要放在构造方法的首行的第一点限制 , 但是可以发现 , 此时会形成一个构造方法间互相调用的死循环状态。 所以在编译时就会出现错误提示 "构造方法递归调用 " , 也就是说在使用 this 调用构造方法时 ,一定要留有出口,不允许出现循环调用的情况。

下边通过一个实例演示 this 调用构造方法的正确使用:
定义一个雇员类(编号、姓名、工资、部门), 在这个类里提供了以下4个构造方法。

  • 无参构造:编号为0,姓名为无名氏,工资为0.0,部门设置为“未定”;
  • 单参构造(传递编号):姓名为“临时工”,工资为800.0,部门为后勤;
  • 双参构造(传递编号、姓名):工资为2000.0,部门为技术部;
  • 全参构造。
//	范例 7 : 利用构造方法互相调用简化代码
class Emp  {
	private int empno;
	private String ename;
	private double sal;
	private String dept;
	
	public Emp(){
		this(0,"无名氏",0.0,"未定");		//调用全参构造
	}
	public Emp(int empno){
		this(empno,"临时工",800.0,"后勤部");		//调用全参构造
	}
	public Emp(int empno, String ename){
		this(empno, ename, 2000.0,"技术部"); 	//调用全参构造
	}
	public Emp(int empno, String ename, double sal, String dept){
		this.empno  =  empno;
		this.ename  =  ename;
		this.sal  =  sal;
		this.dept  =  dept;
	)
	
	public String getInfo(){
		return "雇员编号:"+this.empno+", 姓名:"+this.ename+", 工资:"+this.sal +",部门:"+ this.dept;
	}
	
	// setter、getter略
}

此案例通过“this()”语法的形式,很好地解决了构造方法中代码重复的问题。

1.3 表示当前对象

this 关键字在应用的过程中有一个最为重要的概念——当前对象,而所谓的当前对象指的就是当前正在调用类中方法的实例化对象,下面直接通过一个代码案例来观察。

//	范例 8: 直接输出对象
class Book {
	public void print(){	//调用 print()方法的对象就是当前对象,this就自动与此对象指向同一块内存地址 
		System.out.println("this = " + this);	// this就是当前调用方法的对象
	}   
}
public class TestDemo{
	public static void main(String args[]){
		Book booka = new Book();			//实例化新的 Book 类对象
		System.out.printin("booka = "+ booka);	//主方法中输出 Book类对象
		booka.print();                    	//调用 Book 类的print()方法输出,此时booka 为当前对象
		System.out.printin("---------------------------");
		Book bookb = new Book();           	//实例化新的Book 类对象
		System.out.println("bookb = "+ bookb);	//主方法中输出Book类对象
		bookb.print();                     	//调用 Book类的print)方法输出,此时bookb 为当前对象
	}
}

程序执行结果:

booka = Book@1db9742
this = Book@ldb9742
bookb = Book@106d69c
this = Book@106d69c

此程序首先实例化了两个 Book 类对象,然后在主方法中直接进行对象信息的输出。可以发现每个对象都有一个独立的对象编码,而在使用不同的对象调用 print()方法时, this 的引用也会发生改变,即this为当前对象。

清楚了 this 表示当前对象这一基本特征后,实际上在之前出现的 “this.属性”就属于当前对象中的属性,也就是堆内存中保存的内容。

2️⃣ 引用传递

引用传递是Java中一个让初学者感到费解的概念,但在实际开发中却具有非常重要的作用。为了更好地理解引用传递的相关概念,本节将对引用传递的使用进行全面分析,并详细讲解它在实际开发中的操作意义。

2.1 基本概念

在Java中,基本类型的变量是直接存储值的,而引用类型的变量存储的是对象的引用(内存地址)。当我们把一个引用类型的变量作为参数传递给方法时,实际上是将该引用的副本传递给方法。这意味着方法内部的操作会影响原始对象,因为它们引用同一个对象。

引用传递核心意义是:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存进行内容的修改。通过引用传递,我们可以在方法中修改对象的状态,使得代码更加灵活和易于维护。例如,在集合类中添加或删除元素、修改对象属性等操作都是基于引用传递实现的。

然而,理解引用传递也需要注意一些细节。因为只是传递了引用的副本,重新为参数赋值并不会改变原始的引用,仅在当前方法有效。此外,当将引用作为参数传递给其他方法时,方法之间共享的是同一个对象。这意味着,对于共享的对象进行修改会影响到所有引用该对象的地方。

//	范例 9: 引用传递
class Message {
	private int num=10;		//定义int基本类型的属性
	
	/**
	* 本类没有提供无参构造方法,而是提供有参构造,可以接收num 属性的内容 
	*@param  num 接收num 属性的内容
	*/
	public Message(int num){
		this.num = num;		//为num 属性赋值
	}
	
	public void setNum(int num){
		this.num = num;
	}		
	public int getNum(){
		return this.num;
	}
}

public class TestDemo  {
	public static void main(String args[]){
		Message msg = new Message(30);	//实例化Message 类对象同时传递num 属性内容
		fun(msg);	//引用传递
		System.out.println(msg.getNum());	//输出num 属性内容
	}
	
	/**
	*修改Message 类中的num 属性内容
	*@param temp Message 类的引用
	*/
	public static void fun(Message temp){
		temp.setNum(100);	//修改num 属性内容
	}
}

程序执行结果:

100

此程序首先在 Message 类中只定义了一个 num 属性(int 基本数据类型), 然后利用 Message 类的构造方法进行 num 属性的赋值操作,最后在主方法中调用了 fun()方法,在方法的参数上接收了 Message 类对象的引用,以便可以修改num 属性的内容。而当 fun()方法执行完毕后 temp 断开与堆内存的引用,但是对于堆内存的修改却保存了下来,所以最终的结果是100。此程序的内存关系如下图所示。

在这里插入图片描述
上边这个引用范例是一个标准的引用传递操作,即不同的栈内存指向了同一块堆内存空间,但是在进行引用分析中不得不去考虑一种特殊的类——String 类。

//	范例 10: 引用传递
public class TestDemo{
	public static void main(String args[]){	  
		String msg = "Hello";	//定义String类对象
		fun(msg);	//引用传递
		System.out.println(msg);	//输出msg 对象内容
	}
	
	public static void fun(String temp){ 	//接收字符串引用
		temp = "World";		//改变字符串引用
	}
}

程序执行结果:

Hello

此程序首先定义了一个 String 类的对象,内容为 “Hello”, 然后将此对象的引用传递给 fun()方法中的 temp, 即两个 String 类对象都指向着同一个堆内存空间,但是由于 String 对象内容的变化是通过引用的改变实现的,所以在 fun()方法中所做的任何修改都不会影响到原本的 msg 对象内容,最终的结果依然是“Hello”。本程序的内存分析如下图所示。

在这里插入图片描述
此程序中,因为字符串内容不可改变,String 类对象内容的改变是通过引用的变更实现的,所以 temp = "World"; 实际上是创建了一个新的匿名String对象,但是所有变更都是在 fun() 方法中完成的, 当 fun() 方法执行完毕 temp 将失效,其对应的堆内存空间也将成为垃圾。

以上两个程序范例,第一个利用了 Message 类的对象实现引用传递,而第二个直接利用 String 类对象实现引用,接下来将这两个范例结合在一起来观察引用传递。

//	范例 11: 引用传递
class Message {
	private String info = "xiaoshan";		//定义String类型属性
	
	public Message(String info){    	//利用构造方法设置info属性内容
		this.info = info;
	}
	public void setInfo(String info){
		this.info = info;
	}
	public String getInfo(){
		return this.info;
	}
}

public class TestDemo  {
	public static void main(String args[]){
		Message msg = new Message("Hello"); 	//实例化Message 类对象
		fun(msg);		//引用传递
		System.out.println(msg.getInfo());		//输出info属性内容
	}
	public static void fun(Message temp){		//接收Message 类引用
		temp.setInfo("World");		//修改info属性内容
	}
}

程序执行结果:

World

此程序首先在 Message 类中定义了一个 String 类型的 info 属性,然后在主方法中实例化 Message类对象 msg, 最后将此对象传递到 fun() 方法中。此时 tempmsg 将具备同一块堆内存空间的引用,而在 fun()方法中修改了指定空间的 info 属性内容,所以最终的 info的结果为 “World”。此程序的内存关系如下图所示。

在这里插入图片描述
实际上,上图所示的内存分析流程与上边利用了 Message 类的对象实现引用传递的第一个范例区别不大,唯一的区别是将 int 数据类型的属性替换为了 String 数据类型的属性,由于此时 info 属性是定义在 Message 类中的,所以在 fun()方法中对 info 的修改可以被保存下来。

2.2 实际应用

面向对象是一种可以抽象化描述现实社会事物的编程思想,理论上现实生活中的一切都可以进行合理的抽象。下面实现这样一种类的设计:假如每一个人都有一辆汽车或都没有汽车。很明显,人应该是一个类,而车也应该是一个类,人应该包含一个车的属性,而反过来车也应该包含一个人的属性,面对这样的关系就可以采用下图所示的引用方式来实现。

在这里插入图片描述

//	范例 12: 引用传递 代码实现(无参构造、setter、getter 略,同时本程序定义的是两个简单Java类)
class Member  {
	private int mid;		//人员编号
	private String name;	//人员姓名
	private Car car;		//表示属于人的车,如果没有车则内容为null
	
	public Member(int mid,String name){	
		this.mid = mid;
		this.name = name;
	}

	public void setCar(Car car){
		this.car = car;
	}
	public Car getCar(){
		return this.car;
	}
	
	public String getInfo(){
		return "人员编号:"+this.mid+",  姓名:"+this.name;
	}
}
	
class Car{
	private Member member;	//车属于一个人,如果没有所属者,则为null
	private String pname;	//车的名字
	
	public Car(String pname){
		this.pname = pname;
	}

	public void setMember(Member member){
		this.member = member;
	}
	public Member getMember(){
		return this.member;
	}
	public String getInfo(){
		return "车的名字:"+ this.pname;
	}
}

此程序类设计类完成后,需要对程序进行测试,程序的测试要求主要分为以下两步:根据定义的结构关系设置数据、根据定义的结构关系取出数据。

//	范例 13: 代码测试
public class TestDemo{
	public static void main(String args[]){ 	
		//第一步:根据既定结构设置数据
		Member member = new Member(1,"小山"); 	//独立对象
		Car car = new Car("会漂移的五菱宏光");	//独立对象
		member.setCar(car);		//一个人有一辆车
		car.setMember(member);		//一辆车属于一个人
		
		//第二步:根据既定结构取出关系 
		 System.out.println(member.getCar().getInfo());		//通过人找到车的信息
		 System.out.println(car.getMember().getInfo()); 	//通过车找到人的信息
	}
}

程序执行结果:

车的名字:会漂移的五菱宏光
人员编号:1,  姓名:小山

此程序首先实例化了MemberCar 类各自的对象,然后分别利用各自类中的 setter 方法设置了对象间的引用关系。

这种一对一关系是一种相对比较容易的操作。下面可以进一步设计,例如:每个人都有自己的孩子,孩子还可能有车,那么有如下两种设计方法。

方法一:设计一个表示孩子的类;
存在问题:如果有后代就需要设计一个类,按照这样的思路,如果有孙子,则应该再来个孙子类,如果有曾孙,再来个曾孙类,并且这些类的结构都是完全一样的,这样的设计有些糟糕。

方法二: 一个人的孩子一定还是一个人,与人的类本质没区别,可以在 Member 类里面设计一个属性,表示孩子,其类型也是 Member

//	范例 14:  修改Member类定义
class Member {
	private int mid;		//人员编号
	private String name;	//人员姓名
	private Car car;		//表示属于人的车,如果没有车,则内容为 null
	private Member child;	//表示人的孩子,如果没有,则为null
	
	public Member(int mid, String name){
		this.mid = mid;
		this.name = name;
	}

	public void setCar(Car car){
		this.car = car;
	}
	public Car getCar(){
		return this.car;
	}
	public void setChild(Member child){
		this.child = child;
	}
	public Member getChild(){
		return child;
	}
	
	public String getInfo(){
		return "人员编号:"+this.mid+", 姓名:"+ this.name;
	}
}

class Car{
	private Member member; 	//车属于一个人,如果没有所属者,则为null
	private String pname;	//车的名字
	
	public Car(String pname){
		this.pname = pname;
	}
	
	public void setMember(Member member){
		this.member = member;
	}
	public Member getMember(){
		return this.member;
	}
	
	public String getInfo(){
		return "车的名字:"+this.pname;
	}
}

public class TestDemo{
	public  static void main(String  args[]){
		//第一步:根据既定结构设置数据
		Member member = new Member(1,"小山");	//独立对象
		Member child = new Member(2,"福满多");	//独立对象
		Car car1 = new Car("双肾SUV");	//一辆车
		Car car2 = new Car("玛莎拉蒂");
		member.setCar(car1);	//一个人有一辆车
		car1.setMember(member);	//一辆车属于一个人
		child.setCar(car2);		//一个孩子有一辆车
		car2.setMember(child);	//一个车属于一个孩子
		member.setChild(child);	//一个人有一个孩子
		
		//第二步:根据既定结构取出关系
		System.out.println(member.getCar().getInfo());		//通过人找到车的信息
		System.out.printin(car1.getMember().getInfo());		//通过车找到人的信息
		System.out.println(member.getChild().getInfo());	//通过人找到他孩子的信息
		System.out.println(member.getChild().getCar().getInfo());	//通过人找到他孩子的车的信息
	}
}

程序执行结果:

车的名字:双肾SUV
人员编号:1, 姓名:小山
人员编号:2, 姓名:福满多
车的名字:玛莎拉蒂

此程序在 Member 类中增加了一个表示孩子的属性 “child”, 其类型为 Member 类型,如果一个人有孩子则为其设置一个实例化对象,如果没有则设置为 null。特别需要注意的是,在通过人找到孩子所对应车的信息时使用了代码链的形式 " member.getChild().getCar().getlnfo()", 这类代码一定要观察每一个方法的返回值,如果返回的是一个类的引用,则可以继续调用这个类的方法,而此类代码在以后的开发中也会出现。

🌾 总结

本文详细介绍了Java中的关键字this 以及引用传递的基本概念和实际应用。通过学习this关键字,我们了解到它能够完成调用本类属性、调用本类方法和表示当前对象的功能。在编写代码时,为了避免不必要的麻烦和确保代码的正确性,我们建议在访问类属性时一定要加上this关键字。

同时,我们也探讨了引用传递的基本概念和作用。在Java中,引用传递允许我们将对象的引用副本传递给方法,使得方法内部的操作能够影响到原始对象。这种特性在实际开发中非常重要,可以实现对对象状态的修改和共享的功能,提高代码的可读性和可维护性。

了解和运用this关键字和引用传递对于Java程序员来说至关重要。通过灵活地使用this关键字,我们可以更好地操作和管理对象,避免命名冲突和提高代码的可读性。而引用传递的理解和应用可以帮助我们处理对象之间的关系,实现对象之间的相互作用。

在编写Java代码时,深入理解和熟练运用 this关键字和引用传递是提高代码质量和效率的重要一环。


温习回顾上一篇(点击跳转)
《【Java基础教程】(九)面向对象篇 · 第三讲:深入探究String类——实例化方式及其区别、字符串常量说明、享元设计模式解析、不可改变性特征以及String类的常用方法~》

继续阅读下一篇(点击跳转)《【Java基础教程】(十一)面向对象篇 · 第五讲》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/740380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UMS攸信技术是厦门市工业互联网园区建设的积极参与者与推动者,为数字化转型与工业互联网建设注入新动力

7月6日,厦门市工业互联网一体化进园区“百城千园行”活动第二站走进同安区常青藤科技园,与现场企业共话产业数字化创新发展。 本次活动以“工赋园区 数智未来”为主题,由厦门市工业和信息化局、厦门市同安区人民政府、厦门市同安区工业和信息…

809. 最小公倍数

链接: 链接 题目: 输入两个整数 aa 和 bb,请你编写一个函数,int lcm(int a, int b),计算并输出 aa 和 bb 的最小公倍数。 输入格式 共一行,包含两个整数 aa 和 bb。 输出格式 共一行,包含一个整…

【ELK集群】

ELK集群部署环境准备 配置ELK日志分析系统 192.168.108.67 elk-node1 es、logstash、kibana 192.168.108.189 elk-node2 es、logstash 192.168.108.32 apache logstash 三台虚拟机配置调高 三台机关闭防火墙 改名 1、2台机配置hosts解析文件 1,2台都用系…

Web入门-SpringBoot

SpringBootweb快速入门 需求:使用Spring Boot开发一个web项目,浏览器发起请求/hello后,给浏览器返回字符串”Hello World~“开发步骤 创建SpringBoot工程,并勾选web开发的相关依赖 根据自己idea的版本的不同创建模块即可 &#x…

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数

目录 70. 爬楼梯 (进阶) 322. 零钱兑换 思路 代码 279.完全平方数 思路 70. 爬楼梯 (进阶) 70. 爬楼梯 - 力扣(LeetCode) // 版本一 class Solution { public:int climbStairs(int n) {if (n …

汽配行业数字工厂管理系统解决方案

随着汽车行业的快速发展,汽配行业作为汽车产业链的重要组成部分,也面临着日益增长的市场需求和竞争压力。然而,传统行业在管理方面存在一系列问题,如管理效率低下、业务流程不优化、供应链不透明等。为了应对这些挑战,…

更快更复杂之—Mendix如何支持多种AI部署模式

在过去十年,LCAP市场逐渐崛起的同时,计算能力不断提高、大数据可用性不断增强,预计未来数年,低代码应用平台(LCAP)的市场将增长30%左右,并带动人工智能(AI)迎来新的春天。…

【Spring Boot】单元测试

单元测试 单元测试在日常项目开发中必不可少,Spring Boot提供了完善的单元测试框架和工具用于测试开发的应用。接下来介绍Spring Boot为单元测试提供了哪些支持,以及如何在Spring Boot项目中进行单元测试。 1.Spring Boot集成单元测试 单元测试主要用…

Windows下控制台播放Badapple,opencv的使用,以及代码优化方案

Windows下控制台播放Badapple 环境准备 VS2022编译环境Opencv(对图像进行灰度处理)的配置 可以看我写的这篇文章vs下opencv的配置素材(Badpple的视频文件) 可以私信我FFmpeg(对视频文件进行处理) 让视频文件的声音分离出来生成mp3文件 ffmpeg -i test.mp4 -map 0:v:0 -c copy…

MySQL用户权限管理和密码策略

目录 用户和权限介绍 密码策略 修改密码策略 用户权限管理 赋予权限 收回权限 用户和权限介绍 所有用户的信息都保存在mysql.user 数据表中 可使用desc 查看数据表结构 user 常用字段 部分字段解析 完整的账户 包含host和user,都是char型 都没有默认值 ho…

fork函数,为什么有两次返回?

前言 fork函数用于创建一个新进程,称为子进程,它与旧进程(称为系统调用fork的进程)同时运行,此进程称为父进程。 创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc&a…

网络传输层协议详解(TCP/UDP)

目录 一、TCP协议 1.1、TCP协议段格式 1.2、TCP原理 确认应答机制 超时重传机制 (安全机制) 连接管理机制(安全机制) 滑动窗口 流量控制(安全机制) 拥塞控制 延迟应答(效率机制) 捎带应答(效率机制) ​编辑面向字节流(粘包问题) 缓…

[pyqt5]如何给工具栏图标添加资源文件

第一步新建一个qrc文件 首先新建一个 .qrc 文件&#xff0c;内容格式如下&#xff1a; <RCC><qresource prefix"/" ><file>img/image1.png</file><file>img/image2.png</file><file>img/image3.png</file></qr…

解决win11系统下vivado使用RTL分析闪退、小蓝熊easy anti chat无法启动问题

最近在接触使用vivado时被这个软件庞大的包体和繁多的报错搞得焦头烂额&#xff0c;经过多次尝试&#xff0c;我解决了两个困扰我许久的关乎软件正常使用的问题&#xff0c;将解决办法分享给大家。 一.RTL analysis运行闪退 这个问题关系到程序的正常使用&#xff0c;主要发生…

css animation动画

代码 <!DOCTYPE html> <html ng-app"my_app"><head><meta charset"utf-8"><title></title><script type"text/javascript"></script><style type"text/css">.my-animation {p…

关于海外的应用商店优化

应用商店优化的工作方式与搜索引擎优化 (SEO) 类似&#xff0c;但它有专门为应用商店设计的专业功能。应用商店优化可以帮助应用程序出现在应用商店的顶部结果中&#xff0c;从而提高下载转化率和应用安装量&#xff0c;并且对于我们的应用也有长期可见性。 应用商店优化是一个…

本地用户管理(NETBASE第九课)

本地用户管理(NETBASE第九课) 本地用户&#xff1a;用户本地创建、本地存储、本地登录且只能登录本地一台计算机。 1.认识用户帐户&#xff1a; 1&#xff09;Windows帐户有帐户名、有密码、用户安全标识&#xff08;SID&#xff09; 注:SID安全标识符&#xff08;身份证号…

数据结构-二叉树的代码实现(详解)

内容&#xff1a;二叉树的前、中&#xff0c;后序遍历&#xff0c;层序遍历&#xff0c;二叉树节点个数&#xff0c;叶子节点个数&#xff0c;二叉树高度&#xff0c;第k层节点的个数&#xff0c;查找某个节点&#xff0c;二叉树销毁&#xff0c;判断是否为完全二叉树 目录 前…

科研热点|《电气工程领域高质量科技期刊分级目录(2022版)》公示!

为贯彻落实《关于深化改革 培育世界一流科技期刊的意见》&#xff0c;推进国内外科技期刊的同质等效使用&#xff0c;助力我国科技期刊高质量发展&#xff0c;在中国科协的统一部署下&#xff0c;中国电工技术学会制定《电气工程领域高质量科技期刊分级目录发布工作实施方案&am…

【HarmonyOS】ArkTS学习之页面转场动画的实现

【关键字】 ArkTS、转场动画、PageTransitionEnter、PageTransitionExit 【介绍】 动画交互的实现是一种提升用户体验的方式。动画分为属性属性动画、显示动画、转场动画和路径动画&#xff0c;而转场动画又包含页面间转场、组件内转场和共享元素转场。我觉得页面转场动画挺有趣…