Java this关键字详解(3种用法)

this 关键字是 java 常用的关键字,可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用。

下面我们根据示例分别讲解 this 关键字的作用。

this.属性名

大部分时候,普通方法访问其他方法、成员变量时无须使用 this 前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用 this 前缀。

例 1

假设有一个教师类 Teacher 的定义如下:

 
  1. public class Teacher {
  2. private String name; // 教师名称
  3. private double salary; // 工资
  4. private int age; // 年龄
  5. }

在上述代码中 name、salary 和 age 的作用域是 private,因此在类外部无法对它们的值进行设置。为了解决这个问题,可以为 Teacher 类添加一个构造方法,然后在构造方法中传递参数进行修改。代码如下:

 
  1. // 创建构造方法,为上面的3个属性赋初始值
  2. public Teacher(String name,double salary,int age) {
  3. this.name = name; // 设置教师名称
  4. this.salary = salary; // 设置教师工资
  5. this.age = age; // 设置教师年龄
  6. }

在 Teacher 类的构造方法中使用了 this 关键字对属性 name、salary 和 age 赋值,this 表示当前对象。this.name=name语句表示一个赋值语句,等号左边的 this.name 是指当前对象具有的变量 name,等号右边的 name 表示参数传递过来的数值。

创建一个 main() 方法对 Teacher 类进行测试,代码如下:

 
  1. public static void main(String[] args) {
  2. Teacher teacher = new Teacher("王刚",5000.0,45);
  3. System.out.println("教师信息如下:");
  4. System.out.println("教师名称:"+teacher.name+"\n教师工资:"+teacher.salary+"\n教师年龄:"+teacher.age);
  5. }

运行该程序,输出的结果如下所示。

教师信息如下:
教师名称:王刚
教师工资:5000.0
教师年龄:45

提示:当一个类的属性(成员变量)名与访问该属性的方法参数名相同时,则需要使用 this 关键字来访问类中的属性,以区分类的属性和方法中的参数。

this.方法名

this 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量。

例 2

假设定义了一个 Dog 类,这个 Dog 对象的 run( ) 方法需要调用它的 jump( ) 方法,Dog 类的代码如下所示:

 
  1. /**
  2. * 第一种定义Dog类方法
  3. **/
  4. public class Dog {
  5. // 定义一个jump()方法
  6. public void jump() {
  7. System.out.println("正在执行jump方法");
  8. }
  9. // 定义一个run()方法,run()方法需要借助jump()方法
  10. public void run() {
  11. Dog d = new Dog();
  12. d.jump();
  13. System.out.println("正在执行 run 方法");
  14. }
  15. }

使用这种方式来定义这个 Dog 类,确实可以实现在 run( ) 方法中调用 jump( ) 方法。下面再提供一个程序来创建 Dog 对象,并调用该对象的 run( ) 方法。

 
  1. public class DogTest {
  2. public static void main(String[] args) {
  3. // 创建Dog对象
  4. Dog dog = new Dog();
  5. // 调用Dog对象的run()方法
  6. dog.run();
  7. }
  8. }

在上面的程序中,一共产生了两个 Dog 对象,在 Dog 类的 run( ) 方法中,程序创建了一个 Dog 对象,并使用名为 d 的引用变量来指向该 Dog 对象。在 DogTest 的 main() 方法中,程序再次创建了一个 Dog 对象,并使用名为 dog 的引用变量来指向该 Dog 对象。

下面我们思考两个问题。

1)在 run( ) 方法中调用 jump( ) 方法时是否一定需要一个 Dog 对象?

答案是肯定的,因为没有使用 static 修饰的成员变量和方法都必须使用对象来调用。

2)是否一定需要重新创建一个 Dog 对象?

不一定,因为当程序调用 run( ) 方法时,一定会提供一个 Dog 对象,这样就可以直接使用这个已经存在的 Dog 对象,而无须重新创建新的 Dog 对象了。因此需要在 run() 方法中获得调用该方法的对象,通过 this 关键字就可以满足这个要求。

this 可以代表任何对象,当 this 出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的,它所代表的只能是当前类的实例。只有当这个方法被调用时,它所代表的对象才被确定下来,谁在调用这个方法,this 就代表谁。

将前面的 Dog 类的 run( ) 方法改为如下形式会更加合适,run( ) 方法代码修改如下,其它代码不变。

 
  1. /**
  2. * 第二种定义Dog类方法
  3. **/
  4. // 定义一个run()方法,run()方法需要借助jump()方法
  5. public void run() {
  6. // 使用this引用调用run()方法的对象
  7. this.jump();
  8. System.out.println("正在执行run方法");
  9. }

从第一种 Dog 类定义来看,在 Dog 对象的 run( ) 方法内重新创建了一个新的 Dog 对象,并调用它的 jump( ) 方法,这意味着一个 Dog 对象的 run( ) 方法需要依赖于另一个 Dog 对象的 jump( ) 方法,这不符合逻辑。

第二种 Dog 类定义是当一个 Dog 对象调用 run( ) 方法时,run( ) 方法需要依赖它自己的 jump( ) 方法,与第一种定义类的方法相比,更符合实际情形。

在现实世界里,对象的一个方法依赖于另一个方法的情形很常见,例如,吃饭方法依赖于拿筷子方法,写程序方法依赖于敲键盘方法。这种依赖都是同一个对象两个方法之间的依赖。因此,Java 允许对象的一个成员直接调用另一个成员,可以省略 this 前缀。也就是说,将上面的 run( ) 方法改为如下形式也完全正确。

 
  1. public void run() {
  2. jump();
  3. System.out.println("正在执行run方法");
  4. }

大部分时候,一个方法访问该类中定义的其他方法、成员变量时加不加 this 前缀的效果是完全一样的。

注意:对于 static 修饰的方法而言,可以使用类来直接调用该方法,如果在 static 修饰的方法中使用 this 关键字,则这个关键字就无法指向合适的对象。所以,static 修饰的方法中不能使用 this 引用。并且 Java 语法规定,静态成员不能直接访问非静态成员。

省略 this 前缀只是一种假象,虽然程序员省略了调用 jump() 方法之前的 this,但实际上这个 this 依然是存在的。

this( )访问构造方法

this( ) 用来访问本类的构造方法(构造方法是类的一种特殊方法,方法名称和类名相同,没有返回值。括号中可以有参数,如果有参数就是调用指定的有参构造方法。

例 3

下面定义一个 Student 类,使用 this( ) 调用构造方法给 name 赋值,Student 类的代码如下所示:

 
  1. public class Student {
  2. String name;
  3. // 无参构造方法(没有参数的构造方法)
  4. public Student() {
  5. this("张三");
  6. }
  7. // 有参构造方法
  8. public Student(String name) {
  9. this.name = name;
  10. }
  11. // 输出name和age
  12. public void print() {
  13. System.out.println("姓名:" + name);
  14. }
  15. public static void main(String[] args) {
  16. Student stu = new Student();
  17. stu.print();
  18. }
  19. }

输出结果为:

姓名:张三

注意:

  • this( ) 不能在普通方法中使用,只能写在构造方法中。
  • 在构造方法中使用时,必须是第一条语句。
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用 Feign 进行服务调用时,通常需要在 Spring Boot 应用中配置 FeignClient 接口的实现类。而在 Spring Cloud Gateway 中,我们可以通过配置一个 Filter 来实现 FeignClient 的调用。 具体步骤如下: 1. 首先,在 pom.xml 文件中加入 Feign 的依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> ``` 2. 在应用程序的启动类上添加 `@EnableFeignClients` 注解,以启用 Feign 客户端功能。 ```java @SpringBootApplication @EnableFeignClients public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } } ``` 3. 创建一个 FeignClient 接口,用于定义需要调用的服务。例如: ```java @FeignClient(name = "test-service") public interface TestClient { @GetMapping("/hello") String hello(); } ``` 4. 创建一个 Filter,用于将请求转发给 FeignClient 接口。例如: ```java @Component public class FeignFilter implements GlobalFilter, Ordered { private final TestClient testClient; public FeignFilter(TestClient testClient) { this.testClient = testClient; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String result = testClient.hello(); ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.OK); response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); byte[] bytes = result.getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(bytes); return response.writeWith(Flux.just(buffer)); } @Override public int getOrder() { return -1; } } ``` 在这个 Filter 中,我们注入了上面定义的 TestClient 接口,并在 filter 方法中调用了该接口的 hello 方法。最后,我们将返回的结果写回给客户端。 5. 在 application.yml 文件中添加 FeignClient 的配置: ```yaml spring: application: name: gateway feign: client: config: default: loggerLevel: full ``` 在这个配置中,我们将 FeignClient 的日志级别设置为 `full`,以方便调试。 6. 启动应用程序,并访问 Gateway 的 URL,即可看到 FeignClient 的调用结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哆啦哆啦S梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值