几个关键字(final、static、权限修饰符、super、this、instanceof)

Java知识点总结:想看的可以从这里进入

5、关键字


5.1、类和对象

  1. class:定义一个类
  2. new:创建对象
  3. extend:类的继承
  4. interface:定义接口
  5. implement:实现接口
  6. abstract:抽象类

5.2、权限控制

权限修饰可以用来修饰类的内部结构:属性、方法、构造器、内部类。

而类只能用 public 和 default 这两个来修饰。

权限修饰在一个位置只能出现其中之一。

image-20230424175226867

访问级别是最高的是public表示所有的都可以访问,其次是protected、默认的,最低的是private表示除了自身外都不可访问。

5.3、static

static主要的作用就是用来区分成员变量、方法、内部类、代码块到底属于类本身还是属于类的实例对象。

image-20230131203858567

虽然static非常有用,但过度使用会导致代码之间的耦合过高,并可能降低代码的测试性和灵活性。例如,静态方法无法被覆盖,因此在继承时可能不如实例方法灵活。此外,静态变量如果不被适当管理,也可能导致内存泄漏等问题。因此,合理使用static关键字是关键。

是否可以在static修饰的方法内调用非static方法?

分两种情况描述。

1、如果在静态方法中显示的创建了对象的实例,因为对象已经创建了,所以此时可以调用非static方法

2、在静态方法中没有创建对象实例而直接调用非静态方法,这种情况是不可以的,非静态方法需要创建对象才会分配空间,而静态方法在类加载时便分配了空间,而此时未创建对象,所以在调用时会出现异常。

5.4、final

在 Java 中,final 是一个修饰符,可以用来修饰类、方法和变量。它的含义是“最终的、不可改变的”。

5.4.1、修饰变量

使用final修饰变量后,变量一旦被赋值,其值就不能再被改变。final变量可以是成员变量、局部变量或类变量。

  • final修饰类变量:必须在静态初始化块中或在声明时就进行初始化。

  • final修饰成员变量:必须在构造器执行结束前被初始化(直接指定初始值、代码块中、构造方法中)

  • 修饰局部变量:系统不会为局部变量进行默认的初始化,所以局部变量必须显式赋初值后才能使用, 可以在定义时直接赋初值,也可以在使用前再赋初值,但是只能赋一次。

在这里插入图片描述

对于Java中的普通成员变量(非final修饰),如果没有显式初始化,它们会被自动赋予默认值。

然而对于final成员变量,必须在声明时或者构造器中进行初始化,且只能初始化一次,否则编译器将报错,因为final变量一旦被赋值后就不允许再被修改,所以必须确保其在使用前已正确初始化。

5.4.2、宏替换

对于final 修饰的变量,只要满足三个条件,它就不再是一个变量,而是一个直接量,编译器会把程序中用到该变量的地方直接替换成相应的值。

  1. 使用final 修饰
  2. 在定义时直接指定初始值
  3. 该初始值在编译时可以直接被确定

在Java中直接赋值、被赋值的表达式是基本的算术表达式、是字符串连接运算,没有调用变量方法时,编译器会把这些 final 修饰的变量当成直接量处理。

在这里插入图片描述

5.4.3、修饰类、方法

当修饰一个类时,这意味着这个类不能被继承。

  • 当一个类设计为一个包含静态方法的工具类时,通常会声明为final
  • 当你想确保类的实现不被更改,并且出于安全考虑,比如不允许改变特定的行为或逻辑。

修饰方法时,这个方法不能被其子类重写。如果一个类不是final类,但你希望确保某些核心功能的实现不被子类改变,可以将这些方法单独声明为final。

public class Animal {
    public final void breathe() {
        System.out.println("Breathing air");
    }
}

public class Dog extends Animal {
    // 下面的尝试将会引发编译错误:
    // public void breathe() {
    //     System.out.println("Breathing fast");
    // }
}
  • 保护方法不被修改的语义,尤其是当方法涉及到安全性、权限检查或特定的执行逻辑时。
  • 在设计类的时候,确保核心行为不被更改,同时允许其他功能通过继承进行扩展

final修饰符在类和方法层面上提供了一种有效的机制来控制继承和多态,确保了软件组件的稳定性和可预测性。使用final可以避免不必要的继承和潜在的复杂性增加,有助于维护清晰和简洁的代码结构。

5.4.4、不可变类

在Java中不可变类指的是其实例一旦被创建,其状态(即实例变量的内容)就不能被修改的类。使用不可变类可以提高程序的安全性和简洁性,并且由于不可变对象是线程安全的,这使得它们非常适合在多线程环境下使用。

在Java中像String、包装类等,这些类都是不可变类,一旦创建了不可变类的实例后,其实例变量就不可改变。创建不可变类需要遵循:

  1. 将类声明为final
  2. 类内所有成员变量需要private和final修饰
  3. 提供一个带参数的构造器,根据构造器初始化类中的成员变量
  4. 为成员变量提供get 方法,不提供set 方法
  5. 在需要时通过返回新对象而不是修改当前对象
  6. 确保成员变量的类也是不可变的:
  7. 有必要的话,可以重写Object的hashCod 和 equals 方法

image-20230427191505495

在设计不可变的类时,需要注意引用类型的成员变量,如果引用类型的成员变量是可变的,那就必须采取措施保护该成员变量所引用的对象不会被修改,否则该类就不是不可变类。

1、final:最终的。
修饰变量时必须显式赋初始值,且赋值后不可再更改(基本数据类型是值不可改,引用数据类型是不能再指向其他对象,但是对象内的数据是可改的)。
修饰方法时方法时不能重写
修饰类时类不能被继承。
和Static同时使用,是创建常量。
2、finally是处理异常时配合try、catch一起使用,用于存放那些无论是否出现异常都一定会执行的代码,通常用于释放锁、数据库连接等资源。
3、finalize是Object类的一个方法,是垃圾回收机制的一部分,当对象被回收时,垃圾回收处理器调用此方法。JVM不能保证此方法总被调用。在 Java 9 中该方法已经被标记为废弃,并添加新的 java.lang.ref.Cleaner,提供了更灵活和有效的方法来释放资源。

5.5、this、super

5.5.1、this

在Java中有一个关键字 this,它就是指对象本身,也就是正在执行的方法所属对象的引用。

  • 引用当前对象的属性:当方法的参数或局部变量与类的成员变量同名时,Java往往采用就近原则,先使用局部变量,此时必须添加 this来使用成员变量。
  • 在构造器中引用其他构造器:在一个类中可以有多个构造器,this()可以用来从一个构造器中调用另一个构造器,通常用于构造器重载。这样做可以提高代码的复用性。但是需要注意this需要写在构造方法内的第一行
  • 在方法中调用自身方法:可以直接省略this,当然这个省略只是书写上的省略,实际上this仍然存在
  • 传递当前对象实例:将当前对象作为参数传递给其他方法,或者返回当前对象实例。
  • 在内部类中引用外部类的实例:在内部类中,引用的是内部类的实例。如果需要引用外部类的实例,可以使用 OuterClass.this。
public class Person{
    String name;
    int age;
    public Person(String name,int age){
        //像这种,参数名和实例变量名字相同时就可以使用this关键字区分
        //this.name 表示的就是对象的属性,没带this的就是参数
        this.name = name;
        this.age = age;
    }
    public Person(){
        //调用自身带参的构造方法
        this("张三",20);
    }
    public void say(){
        System.out.println("说话.....");
    }
    public void exercise(){
        System.out.println("运动.....");
        //在方法中可以使用this调用其他方法
        this.say();
        //省略掉this也可以
        say();
        //也可以调用自身属性
        System.out.println("名字是:"+this.name);
    }

}

需要注意的是this关键代表的是对象本身,所以static修饰的方法中不能使用this关键字

5.5.2、super

super:是对上级空间的引用,即对父类空间的引用(并不能代表对象,只是代表一个对象中的一块内存而已),super可以调用父类的属性方法。子父类存在着同名的成员(包括变量和方法)时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员。

  • 可用于访问父类中定义的属性(如果子类没有和父类重名的属性可以不用写super,如果存在重名则必须显式的使用super)
  • 可用于调用父类中定义的方法(如果子类没有和父类重名的方法可以不用写super,如果存在重名则必须显式的使用super)
  • 可用于在子类构造器中调用父类的构造器(写在第一行)
//定义一个动物类
public class Animal {
    String name;
    public Animal(){
        System.out.println("Animal");
    }
    public Animal(String name){
       this();
       this.name = name;
    }
}

//在定义一个子类Dog
public class Dog extends Animal {
    String name;

    public Dog(String name){
        //调用父类构造方法
        super("动物");
        //调用父类的属性
        System.out.println(super.name);
        //自己的属性
        this.name = name;
        System.out.println("Dog:"+name);
    }
}

在这里插入图片描述

super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。但是子类实例化前需要先实例化父类,所以如果都不调用,则默认调用父类的无参构造。

在这里插入图片描述

5.6、instanceof

image-20220413152852010

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辰 羽

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

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

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

打赏作者

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

抵扣说明:

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

余额充值