2021-05-30

java中this用法总结
1,当局部变量和成员变量重名的时候,在方法中使用this表示成员变量以示区分。
复制代码

class Demo{
String str = “这是成员变量”;
void fun(String str){
System.out.println(str);
System.out.println(this.str);
this.str = str;
System.out.println(this.str);
}
}
public class This{
public static void main(String args[]){
Demo demo = new Demo();
demo.fun(“这是局部变量”);
}
}

复制代码

 分析:上面的类Demo中有一个成员变量str和一个局部变量str(类方法中的形式参数),很显然局部变量和成员变量重名,这个时候一般在方法中直接使用str实际上是使用局部变量str,对成员变量str没有任何影响,此时如果需要对成员变量做点什么,就必须使用this关键字。

 有个问题,如果方法中没有str,那么在方法中使用成员变量str会是什么情况呢?实际上是方法内的所有操作都是针对成员变量str的。java编程思想的84页中部有这样一句话:如果在方法内部调用同一个类的另一个方法,就不必使用this。同样,在一个方法中如果没有局部变量和成员变量同名,那么在这个方法中使用成员变量也不必使用this,可以运行下面的代码看看。

复制代码

class Demo{
String str = “这是成员变量”;
void fun(String str1){
System.out.println(str1);
System.out.println(str);
}
}
public class This{
public static void main(String args[]){
Demo demo = new Demo();
demo.fun(“这是局部变量”);
}
}

复制代码
2,this关键字把当前对象传递给其他方法

这里有个很经典的例子,就是java编程思想的85页的例子。我们拿出来仔细研究。
复制代码

class Person{
public void eat(Apple apple){
Apple peeled = apple.getPeeled();
System.out.println(“Yummy”);
}
}
class Peeler{
static Apple peel(Apple apple){
//…remove peel
return apple;
}
}
class Apple{
Apple getPeeled(){
return Peeler.peel(this);
}
}
public class This{
public static void main(String args[]){
new Person().eat(new Apple());
}
}

复制代码

image

这是我自己的认识,也许不正确,看看书中是怎样说的:Apple需要调用Peeler.peel()方法,他是一个外部的工具方法,将执行由于某种原因而必须放在Apple外部的操作(也许是因为该外部方法要应用于许多不同的类,而你却不想重复这些代码)。为了将其自身传递给外部方法,必须使用this关键字。

分析:设想一个场景,假如各种水果去皮的工作都是一样的,只要给我水果,我都按同样的方法去皮。那么结合上面的例子,传进来一个水果,我们吃之前getPeeled(),必须将此水果作为参数传递给外部的peel(),用this来代表自身传递给外部方法。
3,当需要返回当前对象的引用时,就常常在方法写return this;

 这种做法的好处是:当你使用一个对象调用该方法,该方法返回的是经过修改后的对象,且又能使用该对象做其他的操作。因此很容易对一个对象进行多次操作。

复制代码

public class This{
int i = 0;
This increment(){
i += 2;
return this;
}
void print(){
System.out.println("i = " + i);
}
public static void main(String args[]){
This x = new This();
x.increment().increment().print();
}
}

结果为:4
复制代码
4,传递多个参数

  在网上看到this的如下功能:http://blog.csdn.net/anmei2010/article/details/4091227

  image

  其实我觉得这和本文的第二条一样,就是使用this把自身对象作为参数传递给一个工具方法,不同的是这里的工具方法是在本类中而已。其实大家可以分析这两种的区别。

5,在构造器中调用构造器需要使用this。

 一个类有许多构造函数,有时候想在一个构造函数中调用其他构造函数,以避免代码重复,可以使用this关键字。在java编程思想中有这样一段话:通常写this的时候,都是指“这个对象”或者“当前对象”,而且它本身表示对当前对象的引用。在构造器中,如果为this添加了参数列表,那么就有不同的含义。这将产生对符合此参数列表的某个构造器的明确调用;这样调用其他构造函数就有了直接的途径。

 image

 仔细分析:从主函数开始,new Flower()会在内存分配空间,初始化对象,初始化对象是调用构造函数,这里没有写任何参数,当然是调用默认构造函数,就是那个无参的构函数。这个无参的构造函数的第一行代码就是this("hi",122);这里的意思是该无参构造函数又去调用带两个参数的构造函数,来到带两个参数的构造函数,第一行代码是this(s);这行代码自动匹配带一个参数的构造函数,发现Flower(String ss)这个比较匹配,都是String类型的参数。然后调用了带有一个String类型参数的构造函数,打印:只有String类型的参数的构造函数  s = hi;然后回到上一级调用函数,就是带有两个参数的构造函数,打印输出:有String和int类型的参数的构造函数;再回到上一级,就是无参构造函数,打印:默认构造函数。此时构造函数已经初始化完成新建的对象,最后在主函数的最后一行代码中打印:petalCount=122  s=hi。

 画个图看得更明白。

image

有几点要注意:

1,this只可以调用一个构造器,在一个构造器中不能同时调用两个构造器;

2,必须将你所调用的构造器放在最开始的位置,这也解释了为什么不能在一个构造函数中调用两个构造器,那第二个势必不在最开始位置。

3,本例中在带有两个参数的构造函数中可以用this调用其他任意一个只有一个参数的构造函数,这取决你自己,随便调哪一个都可以。

4,在构造函数之外的方法内不能使用this调用构造函数。代码里面注释的都不能正确编译。
6,this总结

1、表示对当前对象的引用!

2、表示用类的成员变量,而非函数参数。

3、用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始!

4、很明显this不能用在static方法中,因为this指代当前对象,而static则无对象之说。
java中this用法总结
1,当局部变量和成员变量重名的时候,在方法中使用this表示成员变量以示区分。
复制代码

class Demo{
String str = “这是成员变量”;
void fun(String str){
System.out.println(str);
System.out.println(this.str);
this.str = str;
System.out.println(this.str);
}
}
public class This{
public static void main(String args[]){
Demo demo = new Demo();
demo.fun(“这是局部变量”);
}
}

复制代码

 分析:上面的类Demo中有一个成员变量str和一个局部变量str(类方法中的形式参数),很显然局部变量和成员变量重名,这个时候一般在方法中直接使用str实际上是使用局部变量str,对成员变量str没有任何影响,此时如果需要对成员变量做点什么,就必须使用this关键字。

 有个问题,如果方法中没有str,那么在方法中使用成员变量str会是什么情况呢?实际上是方法内的所有操作都是针对成员变量str的。java编程思想的84页中部有这样一句话:如果在方法内部调用同一个类的另一个方法,就不必使用this。同样,在一个方法中如果没有局部变量和成员变量同名,那么在这个方法中使用成员变量也不必使用this,可以运行下面的代码看看。

复制代码

class Demo{
String str = “这是成员变量”;
void fun(String str1){
System.out.println(str1);
System.out.println(str);
}
}
public class This{
public static void main(String args[]){
Demo demo = new Demo();
demo.fun(“这是局部变量”);
}
}

复制代码
2,this关键字把当前对象传递给其他方法

这里有个很经典的例子,就是java编程思想的85页的例子。我们拿出来仔细研究。
复制代码

class Person{
public void eat(Apple apple){
Apple peeled = apple.getPeeled();
System.out.println(“Yummy”);
}
}
class Peeler{
static Apple peel(Apple apple){
//…remove peel
return apple;
}
}
class Apple{
Apple getPeeled(){
return Peeler.peel(this);
}
}
public class This{
public static void main(String args[]){
new Person().eat(new Apple());
}
}

复制代码

image

这是我自己的认识,也许不正确,看看书中是怎样说的:Apple需要调用Peeler.peel()方法,他是一个外部的工具方法,将执行由于某种原因而必须放在Apple外部的操作(也许是因为该外部方法要应用于许多不同的类,而你却不想重复这些代码)。为了将其自身传递给外部方法,必须使用this关键字。

分析:设想一个场景,假如各种水果去皮的工作都是一样的,只要给我水果,我都按同样的方法去皮。那么结合上面的例子,传进来一个水果,我们吃之前getPeeled(),必须将此水果作为参数传递给外部的peel(),用this来代表自身传递给外部方法。
3,当需要返回当前对象的引用时,就常常在方法写return this;

 这种做法的好处是:当你使用一个对象调用该方法,该方法返回的是经过修改后的对象,且又能使用该对象做其他的操作。因此很容易对一个对象进行多次操作。

复制代码

public class This{
int i = 0;
This increment(){
i += 2;
return this;
}
void print(){
System.out.println("i = " + i);
}
public static void main(String args[]){
This x = new This();
x.increment().increment().print();
}
}

结果为:4
复制代码
4,传递多个参数

  在网上看到this的如下功能:http://blog.csdn.net/anmei2010/article/details/4091227

  image

  其实我觉得这和本文的第二条一样,就是使用this把自身对象作为参数传递给一个工具方法,不同的是这里的工具方法是在本类中而已。其实大家可以分析这两种的区别。

5,在构造器中调用构造器需要使用this。

 一个类有许多构造函数,有时候想在一个构造函数中调用其他构造函数,以避免代码重复,可以使用this关键字。在java编程思想中有这样一段话:通常写this的时候,都是指“这个对象”或者“当前对象”,而且它本身表示对当前对象的引用。在构造器中,如果为this添加了参数列表,那么就有不同的含义。这将产生对符合此参数列表的某个构造器的明确调用;这样调用其他构造函数就有了直接的途径。

 image

 仔细分析:从主函数开始,new Flower()会在内存分配空间,初始化对象,初始化对象是调用构造函数,这里没有写任何参数,当然是调用默认构造函数,就是那个无参的构函数。这个无参的构造函数的第一行代码就是this("hi",122);这里的意思是该无参构造函数又去调用带两个参数的构造函数,来到带两个参数的构造函数,第一行代码是this(s);这行代码自动匹配带一个参数的构造函数,发现Flower(String ss)这个比较匹配,都是String类型的参数。然后调用了带有一个String类型参数的构造函数,打印:只有String类型的参数的构造函数  s = hi;然后回到上一级调用函数,就是带有两个参数的构造函数,打印输出:有String和int类型的参数的构造函数;再回到上一级,就是无参构造函数,打印:默认构造函数。此时构造函数已经初始化完成新建的对象,最后在主函数的最后一行代码中打印:petalCount=122  s=hi。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个可能的Java实现: ```java import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; public class RentPlanGenerator { private static final double RENT_INCREASE_RATE = 0.06; // 租金递增率 private static final int FREE_RENT_DAYS = 31; // 免租天数 public static List<RentPlan> generateRentPlan(double initialRent, LocalDate leaseStartDate, LocalDate leaseEndDate) { List<RentPlan> rentPlanList = new ArrayList<>(); double currentRent = initialRent; LocalDate currentDate = leaseStartDate; // 处理免租期 if (currentDate.isBefore(leaseStartDate.plusDays(FREE_RENT_DAYS))) { currentDate = leaseStartDate.plusDays(FREE_RENT_DAYS); } while (currentDate.isBefore(leaseEndDate)) { LocalDate nextIncreaseDate = currentDate.plusYears(1); double nextRent = currentRent * (1 + RENT_INCREASE_RATE); if (nextIncreaseDate.isBefore(leaseStartDate.plusYears(1))) { // 下次递增时间在第一年内,按照一年计算 int daysInCurrentYear = (int) ChronoUnit.DAYS.between(currentDate, nextIncreaseDate); rentPlanList.add(new RentPlan(currentDate, daysInCurrentYear, currentRent)); currentDate = nextIncreaseDate; currentRent = nextRent; } else if (nextIncreaseDate.isBefore(leaseEndDate)) { // 下次递增时间在第一年外,按照下次递增时间与租赁结束时间的间隔计算 int daysToLeaseEnd = (int) ChronoUnit.DAYS.between(currentDate, leaseEndDate); rentPlanList.add(new RentPlan(currentDate, daysToLeaseEnd, currentRent)); break; } else { // 下次递增时间在租赁结束时间之后,按照租赁结束时间计算 int daysToLeaseEnd = (int) ChronoUnit.DAYS.between(currentDate, leaseEndDate); rentPlanList.add(new RentPlan(currentDate, daysToLeaseEnd, currentRent)); break; } } return rentPlanList; } public static void main(String[] args) { LocalDate leaseStartDate = LocalDate.of(2021, 3, 1); LocalDate leaseEndDate = LocalDate.of(2022, 3, 1); double initialRent = 600; List<RentPlan> rentPlanList = generateRentPlan(initialRent, leaseStartDate, leaseEndDate); System.out.printf("%-12s%-12s%-12s%n", "时间", "天数", "租金"); for (RentPlan rentPlan : rentPlanList) { System.out.printf("%-12s%-12d%-12.2f%n", rentPlan.getStartDate(), rentPlan.getDays(), rentPlan.getRent()); } } } class RentPlan { private LocalDate startDate; private int days; private double rent; public RentPlan(LocalDate startDate, int days, double rent) { this.startDate = startDate; this.days = days; this.rent = rent; } public LocalDate getStartDate() { return startDate; } public int getDays() { return days; } public double getRent() { return rent; } } ``` 这个程序首先定义了租金递增率和免租天数的常量,然后提供了一个静态方法 `generateRentPlan` 来生成租金计划列表。该方法接受三个参数:初始月租金、租赁开始时间和租赁结束时间。 具体实现时,我们使用循环来逐月生成租金计划。在每次循环中,我们首先计算下次递增租金的时间和金额。然后根据下次递增时间与租赁开始时间的间隔,决定本次循环处理的天数和租金金额。最后将这些信息保存到一个 `RentPlan` 对象中,并添加到租金计划列表中。 在主函数中,我们使用 `generateRentPlan` 方法生成租金计划列表,并以表格形式输出。输出结果如下: ``` 时间 天数 租金 2021-04-01 30 600.00 2021-05-01 31 636.00 2021-06-01 30 674.16 2021-07-01 31 713.57 2021-08-01 31 754.29 2021-09-01 30 796.39 2021-10-01 31 840.94 2021-11-01 30 887.02 2021-12-01 31 934.72 2022-01-01 31 984.12 2022-02-01 28 1035.30 ``` 可以看到,程序正确地根据递增周期和递增率生成了每个月的租金计划,并且考虑了免租期的影响。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值