Skip to content

关键字

instanceof

instanceof 操作符用于检查一个对象是否是某个类的实例或其子类的实例。它在向下转型之前通常用于类型检查,以避免 ClassCastException

在下面的例子中,instanceof 操作符用于检查 myAnimal 是否是 Dog 类的实例,如果是,则进行向下转型。

java
Animal myAnimal = new Dog();

if (myAnimal instanceof Dog) {
    Dog myDog = (Dog) myAnimal;
    myDog.bark();
} else {
    System.out.println("The object is not an instance of Dog.");
}

super

super 关键字在 Java 中用于访问父类的内容,主要包括:

  1. 访问父类的属性:当子类与父类有同名的属性时,可以使用 super 来访问父类的属性。
    java
    public class Parent {  
       public int x = 10;  
    }
    
    public class Child extends Parent {  
       public int x = 20;
    
       public void printX() {  
          System.out.println(super.x); // 访问父类的 x 属性  
       }  
    }
  2. 调用父类的方法:当子类需要调用父类的方法时,可以使用 super
    java
    public class Parent {  
       public void method() {  
          // ...  
       }  
    }
    
    public class Child extends Parent {  
       public void anotherMethod() {  
          super.method(); // 调用父类的 method 方法  
       }  
    }
  3. 在构造方法中调用父类的构造方法:使用 super(...) 可以在子类的构造方法中调用父类的构造方法。这是 Java 中创建对象时初始化父类部分的标准方式。
    java
    public class Parent {  
       public Parent(int x) {  
          // ...  
       }  
    }
    
    public class Child extends Parent {  
       public Child(int x) {  
          super(x); // 调用父类的构造器  
       }  
    }

需要注意的是,super(...)this(...) 都必须在构造方法的第一行使用,并且它们不能同时出现在一个构造方法中。

this

this 关键字在 Java 中主要用于以下情况:

  1. 引用当前对象的属性:当局部变量和类的成员变量同名时,可以使用 this 来区分。
    java
    public class MyClass {  
       private int x;
    
       public MyClass(int x) {  
         this.x = x; // 使用 this 来引用类的成员变量  
       }  
    }
  2. 调用当前对象的方法:有时,你可能需要在方法内部调用同一个类的另一个方法。
    java
    public class MyClass {  
       public void method1() {  
          // ...  
          method2(); // 直接调用  
          this.method2(); // 使用 this 来调用,与直接调用效果相同  
       }
       
        public void method2() {  
          // ...  
        }  
    }
  3. 在构造方法中调用另一个构造方法:从 Java 11 开始,你可以在构造器中使用 this(...) 来调用同一类中的另一个构造方法。注意,这种调用必须是构造方法中的第一条语句。
    java
    public class MyClass {  
       public MyClass() {  
          this(10); // 调用带有参数的构造器  
       }
       
       public MyClass(int x) {  
          // ...  
       }  
    }
  4. 返回当前对象的引用:在某些情况下,你可能希望方法返回调用它的对象本身。
    java
    public class MyClass {  
       public MyClass someMethod() {  
          // ...  
          return this; // 返回当前对象的引用  
       }  
    }

final

  1. 修饰变量
    • final 修饰基本数据类型的变量,表示该变量的值不能被修改。
    • final 修饰引用类型的变量,表示该变量的引用不能被修改,但是对象的内容可以被修改。例如数组引用不变,但是数组元素可以改变。
    java
    public class Main {
        public static void main(String[] args) {
            final int MY_CONSTANT = 10;
            // MY_CONSTANT = 20; // 错误:不能修改 final 变量
            System.out.println(MY_CONSTANT);
    
            final int[] arr = {1, 2, 3};    
            // arr = new int[] {4, 5, 6}; // 错误:不能修改 final 引用
            arr[0] = 4; // 可以修改数组元素
        }
    }
  2. 修饰方法:final 修饰的方法不能被子类重写。
    java
    class Parent {
        final void display() {
            System.out.println("This is a final method.");
        }
    }
    
    class Child extends Parent {
        // void display() { // 错误:不能重写 final 方法
        //     System.out.println("Trying to override final method.");
        // }
    }
  3. 修饰类:final 修饰的类不能被继承。
    java
    final class FinalClass {
        void display() {
            System.out.println("This is a final class.");
        }
    }
    
    // class Child extends FinalClass { // 错误:不能继承 final 类
    // }

static

static 关键字修饰的变量、常量和方法称为静态变量、静态常量和静态方法。

例如下面的场景中:在球类和圆类中都需要使用到 PI 常量,此时就不建议在两个类中分别定义,因为这样会导致虽然是同一个名称的常量,但是分配到了不同的内存空间里。为了解决这个问题,可以使用 static 关键字定义静态变量和静态常量。

调用的语法:

java
类名.静态变量名
类名.静态方法名

示例:

java
public class Constants {
    public static final double PI = 3.14159;
}

public class Circle {
    public double getArea(double radius) {
        return Constants.PI * radius * radius;
    }
}

public class Ball {
    public double getVolume(double radius) {
        return 4.0 / 3.0 * Constants.PI * radius * radius * radius;
    }
}

25021210.png

图 PI 常量在内存中被共享的情况

需要注意的是,在静态方法中不能直接访问非静态成员,因为静态方法在类加载时就已经存在,而非静态成员是在对象创建时才会被初始化。并且在静态方法中不能使用 this 关键字。

例如下面的示例中,getArea() 方法是静态方法,不能直接访问 radius 成员变量:

java
public class Circle {

    public static final double PI = 3.14159;
    double radius;

    public static double getArea() {
        return Constants.PI * radius * radius;
    }
}

如果需要在执行类时,希望先执行类的初始化动作,则可以使用 static 代码块。static 代码块在类加载时执行,只执行一次。

java
public class Circle {
    static {
        // 在这里编写初始化代码
    }
}

transient

transient 关键字用于修饰类的字段,指示垃圾收集器在序列化对象时忽略这些字段。这意味着当对象被序列化(通常是为了保存到文件或通过网络传输)时,transient 修饰的字段不会被包含在序列化过程中。

这种机制对一些特定情况非常有用,例如:

  1. 敏感数据的保护:如果对象中包含敏感信息(如密码),而不希望在序列化时保存这些信息,可以使用 transient 关键字。
  2. 非持久性数据:如果某个字段的数据是临时的,或者在重建对象时可以通过其他方法恢复,不需要序列化它。
  3. 避免循环引用问题:在对象图中,如果序列化字段可能导致循环引用(即对象相互引用形成闭环),可以使用 transient 避免这些字段的序列化。

需要注意的是,使用 transient 关键字的字段在反序列化对象时,其值将会是其类型的默认值(如对象类型为 null,整数类型为 0,布尔类型为 false)。因此,如果需要在反序列化后恢复这些字段的值,需要额外的逻辑来处理。

在下面的代码中,password 字段被标记为 transient,因此在序列化时不会被保存。序列化和反序列化后,password 字段的值将会变为 null

java
import java.io.*;

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String username;
    private transient String password; // 不希望序列化的字段

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{username='" + username + "', password='" + password + "'}";
    }

    public static void main(String[] args) {
        User user = new User("john_doe", "secret123");
        System.out.println("Before serialization: " + user);

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
            oos.writeObject(user);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
            User deserializedUser = (User) ois.readObject();
            System.out.println("After serialization: " + deserializedUser);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
编程洪同学服务平台是一个广泛收集编程相关内容和资源,旨在满足编程爱好者和专业开发人员的需求的网站。无论您是初学者还是经验丰富的开发者,都可以在这里找到有用的信息和资料,我们将助您提升编程技能和知识。
专业开发
高端定制
售后无忧
站内资源均为本站制作或收集于互联网等平台,如有侵权,请第一时间联系本站,敬请谅解!本站资源仅限于学习与参考,严禁用于各种非法活动,否则后果自行负责,本站概不承担!