Java基础4—关键字


前面提到了多种关键字,比如static、final,下面我们就来看看这些关键字到底有什么用?

1. static

在《Java编程思想》P86页有这样一段话: “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

简而言之,static的作用就是方便在没有创建对象的情况下来调用变量或方法。

static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。

使用场景

  1. 修饰成员变量和成员方法: 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被 static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:类名.静态变量名 类名.静态方法名()

    static变量也称作静态变量,静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化,且static成员变量的初始化顺序按照定义的顺序进行初始化。

  2. 静态代码块: 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次.

  3. 静态内部类(static 修饰类的话只能修饰内部类): 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非 static 成员变量和方法。

  4. 静态导包(用来导入类中的静态资源,1.5 之后的新特性): 格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。

例题:

来看下面这个例子,先思考一下类加载的过程,以及静态变量的使用,然后考虑结果。

public class Singleton {
    private static Singleton instance = new Singleton();	// 1: instance = null
    	
    public static int x = 0;	// 2: 	x = 0	 7: x = 0
    public static int y;	// 3:		y = 0
    
    public Singleton() {	// 4:	
        x++;	// 5: x = 1
        y++;	// 6: y = 1
    }

    public static Singleton getInstance() {
        return instance;
    }
    public static void main(String[] args) {
        Singleton instance = getInstance();
        System.out.println(instance.x);	// 0
        System.out.println(instance.y);	// 1
    }
}

我们来推导一下上面语句的执行过程:

  1. 首先将类编译成字节码文件,并加载到JVM中
  2. 然后就是连接过程了,连接过程分为三步,
    1. 验证:确保class文件的字节流中包含的信息符合当前虚拟机的要求,比如文件格式、语句检查、字节码验证等
    2. 准备:此阶段为类变量(静态变量)分配内存,并设置默认值,一般分配在方法区(元数据区)
    3. 解析:将类中的符号引用转换为直接引用,指向方法或变量在方法区的内存位置。
  3. 前面都是准备阶段,现在是初始化阶段,包括正式执行代码,首先为静态变量赋值,然后执行静态代码块中的内容,具体过程为:父类静态变量->父类静态代码块->子类静态变量->子类静态代码块。

所以上面代码的执行过程是先为所有静态变量赋初始值,然后执行静态代码块中的内容,最后结果是0,1

如果是下面的代码呢?结果是1,1,请思考。

public class Singleton {
    public static int x = 0;
    public static int y;
    
    private static Singleton instance = new Singleton();
    
    public Singleton() {
        x++;
        y++;
    }
    
    public static Singleton getInstance() {
        return instance;
    }
    
    public static void main(String[] args) {
        Singleton instance = getInstance();
        System.out.println(instance.x);
        System.out.println(instance.y);
    }
}

2. final

final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。

一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

final变量

final成员变量表示常量,只能被赋值一次,赋值后值不再改变(final要求地址值不能改变)。因此final修饰成员变量时,必须要显示初始化。

final方法

final修饰方法一般有两个原因,

  • 一是为了锁定方法,避免在继承的时候被修改
  • 二是提高效率,因为final方法在编译时已经静态绑定,不需要在运行时再动态绑定。

final类

当用final修饰一个类时,表明这个类不能被继承。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。


3. this

this 关键字用于引用类的当前实例。 例如:

class Manager {
    Employees[] employees;

    void manageEmployees() {
        int totalEmp = this.employees.length;
        System.out.println("Total employees: " + totalEmp);
        this.report();
    }

    void report() { }
}Copy to clipboardErrorCopied

在上面的示例中,this 关键字用于两个地方:

  • this.employees.length:访问类 Manager 的当前实例的变量。
  • this.report():调用类 Manager 的当前实例的方法。

此关键字是可选的,这意味着如果上面的示例在不使用此关键字的情况下表现相同。 但是,使用此关键字可能会使代码更易读或易懂。


4. super

super 关键字用于从子类访问父类的变量和方法。 例如:

public class Super {
    protected int number;

    protected showNumber() {
        System.out.println("number = " + number);
    }
}

public class Sub extends Super {
    void bar() {
        super.number = 10;
        super.showNumber();
    }
}Copy to clipboardErrorCopied

在上面的例子中,Sub 类访问父类成员变量 number 并调用其父类 Super 的 showNumber() 方法。

使用 this 和 super 要注意的问题:

  • 在构造器中使用 super() 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。
  • this、super 不能用在 static 方法中。

简单解释一下:

被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象;所以, this 和 super 是属于对象范畴的东西,而静态方法是属于类范畴的东西

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值