您的位置:首页 > 编程语言 > Java开发

java中类的继承,虚拟机会如何进行父类和子类的初始化加载

2019-04-13 10:18 525 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_38821502/article/details/89278562

java中类的继承,虚拟机会如何进行父类和子类的初始化加载

1、变量是 static final 修饰的“编译期常量”,如 public static final String a = “JD”;

public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static final String a = "JD";
static {
System.out.print("OK");
}
}

答案

JD

2、变量是 static final 修饰的“非编译期常量”,如 public static final String a = new String(“JD”);

public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static final String a = new String("JD");
static {
System.out.print("OK");
}
}

答案

OKJD

3、static 变量域不是 final,如 public static String a = “JD”;

public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static String a = "JD";
static {
System.out.print("OK");
}
}

答案

OKJD

4、static 变量域不是 final,如 public static String a = new String(“JD”);

public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static String a = new String("JD");
static {
System.out.print("OK");
}
}

答案

OKJD

对变量的调用时
5、子类中的变化

public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
// 测试:只能选择其中一种一条语句
public static final String c = "C";
// public static  String c = "C";
// public static final String c = new String("C");
// public static String c = new String("C");
}

答案

public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
// 测试:只能选择其中一种一条语句
public static final String c = "C"; //C
// public static String c = "C"; //ABC
// public static final String c = new String("C"); //ABC
// public static String c = new String("C"); // ABC
}

6、父类中的变化

public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
// 测试:只能选择其中一种一条语句
public static final String c = "C";
// public static  String c = "C";
// public static final String c = new String("C");
// public static String c = new String("C");
}
class B extends A {
static {
System.out.print("B");
}
}

答案

public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
// 测试:只能选择其中一种一条语句
public static final String c = "C"; // C
// public static String c = "C";//AC
// public static final String c = new String("C"); //AC
// public static String c = new String("C"); //AC
}
class B extends A {
static {
System.out.print("B");
}
}

对方法的调用时
7、子类对象调用父类的方法

public class Test {
public static void main(String[] args) {
B b = new B();
b.get();
}
}
class A {
public void get() {
System.out.println("M");
}
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
}

答案

ABM

8、子类对象调用子类的方法

public class Test {
public static void main(String[] args) {
B b = new B();
b.get();
}
}
class A {

static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
public void get() {
System.out.println("M");
}
}

答案

ABM

9、父类对象调用父类方法

public class Test {
public static void main(String[] args) {
A a = new A();
a.get();
}
}
class A {
public void get() {
System.out.println("M");
}
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}

}

答案

AM

总结:
1、如果一个 static final 变量是"编译期常量",就像 public static final String a = “JD”;那样,那么这个值不需要对 Test2 类进行初始化就可以读取,否则需要对Test2类进行初始化后才能调用。
2、但是,如果只是将一个变量的域设置为 static 和 final 的,那不足以确保这种行为。例如,对 public static final String a = new String(“JD”);的访问将强制对 Test2 类进行初始化,因为它不是一个"编译期常量"。
3、如果一个 static 变量域不是 final,那么在对它进行访问时,总是要求在它被读取之前,要先进行链接 (为这个域分配存储空间) 和初始化 (初始化该存储空间) 就像 public static String a = “JD”;。
4、子类对象调用子类中的变量时(B.c),需要对父类和子类进行初始化,如果是一个 static final 常量,就可以直接调用,不需要对父类进行初始化。子类
5、对象调用父类中的变量时(B.c),不需要对子类进行初始化,直接初始化父类就可,但是如果是一个 static final 常量,就可以直接调用。
6、子类对象调用父类或子类的方法时,都需要对父类和子类进行初始化。
7、父类对象调用父类方法,需要对父类进行初始化,但不需要对子类进行初始化。

参考
https://www.cnblogs.com/hglibin/p/10298650.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: