【Java】常用关键字

36 阅读3分钟

扩展

  1. volatile

static

参考笔记一,P29.14。

1:为什么非静态内部类的成员不能声明为}$static

因为由static声明或定义的变量为所有拥有它的对象共享,而内部类属于外部类,故内部类的static变量为所有外部类的对象共享,这会导致内部类被提升为外部类、则内部类中的局部变量将无意义。==除非是静态内部类==;

2:为什么不能在成员方法和类方法中定义类变量?

因为为类变量分配内存空间是在类加载第二过程的准备阶段,而成员方法和类方法是在类加载完成后再进行初始化,此时已不能再为类变量分配内存空间。

final

1:赋初值。

常量仅能在声明static int a = 10或构造器(包括:代码块、构造方法)内赋初值。

2:常将常量声明为static的原因。

若没有static,则属于对象成员,则在每个对象实例化时都会创建一个副本,占据堆空间;而声明为static,则会在类加载时被加载进方法区的全局数据访问区中,即只有一个副本,节省空间。并且,声明为static,还可以在静态代码块中赋初值。

3:常量不可变吗?

常量不可变,这可谓是定理,相信大家也一直是这么学习和理解的。可实际上可变,例如:通过反射,

大家是否还记得:

  1. 反射可以跳过泛型检查。(详述可查阅博文《[Java]反射》中的【反射运用:跳过泛型检查】一栏)
  2. 在泛型内有一个概念叫做“泛型擦除”。(详述可查阅博文《[Java]泛型》中的【泛型通配符】一栏)

我们来回顾一下。

  1. “泛型检查”是指泛型的限制作用作用于编译阶段,若传入数据的类型与泛型的类型实参不符,则编译不通过。而反射作用于方法区,且不经过编译阶段,故可以跳过泛型检查。
  2. “泛型擦除”是指在编译完成后,JVM会将泛型的类型实参“擦除”,并上转为其父类(Object)。

我的猜想:反射可以跳过“泛型检查”,反射也可以修改常量(final)。那么,我们所知的“由final修饰的常量不可变”是不是如“泛型擦除”一般,仅是作用于编译阶段,用于限制变量的修改(仅能赋值一次,也就是初始化)。

PS:我暂且未查阅到相关文章,以上出于我的理解。可能不全对,但目前,这有利于我的学习理解。

abstract

参考笔记一,P32.8。

1:为什么抽象类的子类(非抽象类)必须实现抽象类所有抽象方法?

因为若子类不全部实现抽象类的所有抽象方法,则必须是抽象类,而抽象类不能实例化。

this

  1. 调用成员变量、成员方法(可省略)。
  2. 调用其他构造方法。不能调用参数多于自身的构造方法,因为this必须置于第一行,故无法新定义“多出部分”的参数,除非“多出部分”使用常量。
  3. 区分局部变量与全局变量。
  4. 作为返回值,返回实例本身。
  5. 类方法中不能使用this,因为this代表实例,而类方法的初始化执行于类加载,此时还未实例化,即无实例。

super

  1. 调用父类被覆盖的成员变量、成员方法。
  2. 调用父类的构造方法。未使用super时,默认调用父类无参构造方法。且由于thissuper不能共存,故存在this时,则不会再默认调用父类的无参构造方法。
  3. super可认为是父类引用,实则不是,因为父类未实例化,无引用。

本文持续更新中。。。