【Java】this、super关键字,代码块介绍

简介: 【Java】this、super关键字,代码块介绍

一. this引用

1. this引用的介绍

this引用是成员方法的参数之一,不需要用户传递实现,由编译器自动完成,也就是说,这个参数用户是看不到的,但用户可使用这个参数。

this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。 只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

this 引用的是调用成员方法的对象。

2. this引用的特性

this的类型:对应类 类型引用,即哪个对象调用就是哪个对象的引用类型

this只能在"成员方法"中使用

在"成员方法"中,this只能引用当前对象,不能再引用其他对象

this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收73d8c9be8b2a4960a39693770de0ac9a.png

  1. 用户也可以将由编译器实现的形参this手动给出,但实参中不能有其对应的对象的引用,否则会报错

73d8c9be8b2a4960a39693770de0ac9a.png

3. this引用所解决的问题

看下面给出的代码,当方法形参名与成员变量名相同;但我们没有手动通过this引用去调用成员变量;

看执行结果可以发现此时并没有完成对于成员变量的赋值,因为在方法中遵循局部变量优先的原则,就不会去访问成员变量,只是形参自己给自己赋值而已

public class Date {
    public int year;
    public int month;
    public int day;
    public void setDay(int year, int month, int day){
        year = year;
        month = month;
        day = day;
    }
    public void printDate(){
        System.out.println(year + "/" + month + "/" + day);
    }
    public static void main(String[] args) {
       // 构造三个日期类型的对象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
        // 对d1,d2,d3的日期设置
        d1.setDay(2022,8,15);
        d2.setDay(2022,8,16);
        d3.setDay(2022,8,17);
        // 打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

执行结果:

73d8c9be8b2a4960a39693770de0ac9a.png

要解决这里的问题只需要通过this去访问成员变量即可,此时就可以区分形参和成员变量了

public void setDay(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
}

执行结果:73d8c9be8b2a4960a39693770de0ac9a.png

4. this的三种用法

  • this.成员变量
  • this.成员方法
  • this( );访问构造方法(在构造方法博客中介绍)

二. super关键字

1. super关键字的介绍

由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成 员时,该如何操作?


直接访问是无法做到的,因为局部优先的的原则,会直接访问子类的成员。


Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。


【注意事项】


super只能在非静态方法中使用

super可以用来在子类方法中,访问父类的成员变量和方法。

public class Base {
    int a;
    int b;
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}
class Derived extends Base{
    int a; // 与父类中成员变量同名且类型相同
    char b; // 与父类中成员变量同名但类型不同
    // 与父类中methodA()构成重载
    public void methodA(int a) {
        System.out.println("Derived中的method()方法");
    }
    // 与基类中methodB()构成重写
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
// 对于同名的成员变量,直接访问时,访问的都是子类的
        a = 100; // 等价于: this.a = 100;
        b = 101; // 等价于: this.b = 101;
// 注意:this是当前对象的引用
// 访问父类的成员变量时,需要借助super关键字
// super是获取到子类对象中从基类继承下来的部分
        super.a = 200;
        super.b = 201;
// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
        methodA(); // 没有传参,访问父类中的methodA()
        methodA(20); // 传递int参数,访问子类中的methodA(int)
// 如果在子类中要访问重写的基类方法,则需要借助super关键字
        methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到
        super.methodB(); //访问基类的methodB()
    }
}

2. super的三种用法

  • super.子类中从父类继承的成员变量
  • super.子类中从父类继承的成员方法
  • super( );调用父类的构造方法(在构造方法博客中介绍)

三. super和this的比较

1. 相同点

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

2. 不同点

this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用(注意不是父类的引用,子类继承父类并没有创建父类对象)

在非静态成员方法中,this用来访问本类的方法和属性,子类对象中如果没有重名现象的发生,this也可以访问到父类继承下来的方法和属性;但super只能用来用来访问父类继承下来的方法和属性73d8c9be8b2a4960a39693770de0ac9a.png

在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现

子类构造方法中一定会存在super(…)的调用,用户没有写编译器也会自动给出;但是要在子类构造方法中调用子类其他构造方法,需要用户手动添加this(…)

四. 代码块概念以及分类

使用 { } 定义的一段代码称为代码块。

根据代码块定义的位置以及关键字,又可分为以下四种:

  • 普通代码块
  • 构造代码块
  • 静态代码块
  • 同步代码块

1. 普通代码块

普通代码块:定义在方法中的代码块, 其内的变量只在代码块中有效,这种用法较少见。

public class Main{
    public static void main(String[] args) {
        { //直接使用{ }定义,普通方法块
            int x = 10 ;
            System.out.println("x1 = " +x);
        }
        int x = 100 ;
        System.out.println("x2 = " +x);
    }
}

2. 构造代码块

定义在类中的代码块(不加修饰符)。

也叫:实例代码块。构造代码块一般用于初始化实例成员变量。

public class Student{
    //实例成员变量
    private String name;
    private String gender;
    private int age;
    //实例代码块
    {
        this.name = "xinxin";
        this.age = 21;
        this.gander = "nan";
        System.out.println("I am instance init()!");
    }
    public void show(){
        System.out.println("name: "+name+" age: "+age+" gender: "+gender);
    }
}
public class Main {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.show();
    }
}

3. 静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

public class Student{
    private String name;
    private int age;
    private static String classRoom;
    //实例代码块
    {
        this.name = "xin";
        this.age = 21;
        System.out.println("I am instance init()!");
    }
    // 静态代码块
    static {
        classRoom = "rj2104";
        System.out.println("I am static init()!");
    }
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();
    }
}

4. 注意事项

  • 静态代码块不管生成多少个对象,其只会执行一次
  • 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  • 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
  • 实例代码块只有在创建对象时才会执行
目录
相关文章
|
10月前
|
缓存 安全 Java
Volatile关键字与Java原子性的迷宫之旅
通过合理使用 `volatile`和原子操作,可以在提升程序性能的同时,确保程序的正确性和线程安全性。希望本文能帮助您更好地理解和应用这些并发编程中的关键概念。
261 21
|
9月前
|
缓存 运维 Java
Java静态代码块深度剖析:机制、特性与最佳实践
在Java中,静态代码块(或称静态初始化块)是指类中定义的一个或多个`static { ... }`结构。其主要功能在于初始化类级别的数据,例如静态变量的初始化或执行仅需运行一次的初始化逻辑。
298 4
|
9月前
|
Java C语言
课时8:Java程序基本概念(标识符与关键字)
课时8介绍Java程序中的标识符与关键字。标识符由字母、数字、下划线和美元符号组成,不能以数字开头且不能使用Java保留字。建议使用有意义的命名,如student_name、age。关键字是特殊标记,如蓝色字体所示。未使用的关键字有goto、const;特殊单词null、true、false不算关键字。JDK1.4后新增assert,JDK1.5后新增enum。
187 4
|
9月前
|
Java
java构造方法,构造代码块,静态代码块的执行顺序
本文介绍了Java中构造方法、构造代码块和静态代码块的执行顺序。静态代码块用`static`声明,在JVM加载类时执行一次;构造代码块在每次创建对象时执行,先于构造方法;构造方法用于对象初始化,创建对象时调用。示例代码展示了这三者的输出顺序,并解释了它们的区别和应用场景。
288 1
|
8月前
|
存储 安全 Java
深入理解 Java 中的 instanceof 关键字
本文深入解析了 Java 中的 `instanceof` 关键字,探讨其在类型判断中的作用。作为二元操作符,`instanceof` 可用于检查对象是否为某类实例或实现特定接口,避免类型转换异常 (`ClassCastException`)。文章通过多态性下的类型判断、安全类型转换、接口实现检测及集合元素类型判定等实际应用场景,展示了 `instanceof` 的强大功能。掌握该关键字可提高代码健壮性,确保运行时类型安全。
576 0
|
12月前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
323 5
Java 并发编程——volatile 关键字解析
|
11月前
|
Java 编译器 开发者
Java中的this关键字详解:深入理解与应用
本文深入解析了Java中`this`关键字的多种用法
1716 9
|
11月前
|
JSON Java 数据挖掘
利用 Java 代码获取淘宝关键字 API 接口
在数字化商业时代,精准把握市场动态与消费者需求是企业成功的关键。淘宝作为中国最大的电商平台之一,其海量数据中蕴含丰富的商业洞察。本文介绍如何通过Java代码高效、合规地获取淘宝关键字API接口数据,帮助商家优化产品布局、制定营销策略。主要内容包括: 1. **淘宝关键字API的价值**:洞察用户需求、优化产品标题与详情、制定营销策略。 2. **获取API接口的步骤**:注册账号、申请权限、搭建Java开发环境、编写调用代码、解析响应数据。 3. **注意事项**:遵守法律法规与平台规则,处理API调用限制。 通过这些步骤,商家可以在激烈的市场竞争中脱颖而出。
|
12月前
|
缓存 安全 Java
Java volatile关键字:你真的懂了吗?
`volatile` 是 Java 中的轻量级同步机制,主要用于保证多线程环境下共享变量的可见性和防止指令重排。它确保一个线程对 `volatile` 变量的修改能立即被其他线程看到,但不能保证原子性。典型应用场景包括状态标记、双重检查锁定和安全发布对象等。`volatile` 适用于布尔型、字节型等简单类型及引用类型,不适用于 `long` 和 `double` 类型。与 `synchronized` 不同,`volatile` 不提供互斥性,因此在需要互斥的场景下不能替代 `synchronized`。
3437 3
|
JavaScript 前端开发 Java
java中的this关键字
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。自学前端2年半,正向全栈进发。若我的文章对你有帮助,欢迎关注,持续更新中!🎉🎉🎉
208 9