面试 0:类加载顺序、抽象类和接口的区别

01 类加载顺序

  • 代码:
package com.rjxy.testAbstract;

public class Animal {
	public String test = "AnimalFeild";
	public static String testStatic = "AnimalStaticFeild";
	public Animal() {
		System.out.println("我是animal中的无参数构造方法");
	}
	{
		System.out.println("我是animal中的普通程序块"+this.test);
	}
	static {
		testStatic();
		System.out.println("我是animal中的静态代码块"+testStatic);
	}
	public void test() {
		System.out.println("我是animal中的普通方法");
	}
	public static void testStatic() {
		System.out.println("我是animal类中静态方法");
	}
}

package com.rjxy.testAbstract;

public class Person extends Animal{
	public String test = "PersonFeild";
	public static String testStatic = "PersonStaticFeild";
	public Person() {
		System.out.println("我是Person中的无参数构造方法");
	}
	{
		System.out.println("我是Person中的普通程序块"+this.test);
	}
	static {
		testStatic();
		System.out.println("我是Person中的静态代码块"+testStatic);
	}
	public void test() {
		System.out.println("我是Person中的普通方法");
	}
	public static void testStatic() {
		System.out.println("我是Person类中静态方法");
	}
}

package com.rjxy.testAbstract;

import org.junit.jupiter.api.Test;

public class Application {
	@Test
	public void test() {
		Person p = new Person();
	}
}

  • 运行结果:
    在这里插入图片描述
  • 解释

    分配空间:当JVM进程启动,向OS索要内存空间。OS给它分配一定的内存空间后,JVM再给自己的各个区分配内存空间,如堆区、方法区、栈区。
    加载顺序
    先由bootstrap类加载器加载必要的类,如java.lang包下的类。应用类加载器加载Application,之后初始化,从main方法入口进入,执行到new Person()时,JVM发现这个是主动使用。所以就要加载、初始化这个Person类,但有父才能有子, 所以必须先加载、初始化它的父类。因此父类Animal的Class文件率先被加载到方法区中,在堆中也会产生一个描述该Class文件的对象。然后就是加再子类的过程。加载完这两个类进行初始化,父类先被初始化,所以①②先被输出。子类再被初始化,所以③④被输出。
    注意:为类变量分配内存是在链接的准备阶段完成的,在方法区中,每个Class类模板都有其对应的静态空间,用以保存静态变量、静态方法、静态块
    new 关键字真正开始执行。先在堆中分配内存空间,之后加载父类非静态成员(属性、方法、块、构造方法依次)。执行块代码,执行构造方法代码。同样的,加载子类非静态成员,执行子类块,执行子类构造方法。
    最后将栈中的引用执行堆中。

    在这里插入图片描述

02 抽象类和接口的区别

  • 抽象类
  1. 类成员
    属性:正常类属性能有的,抽象类属性也能有
    方法:一般方法也可以有。抽象方法不能用private修饰,因为这样不能被子类继承。因为抽象类本身的意义就在于对具体类的抽象,最终是要被继承的。缺省情况下为public,通过eclipse可看出。
    块:一般的、静态的都存在
    构造方法:可以存在,但不能在main中 new,原因是抽象类中可能存在未实现的方法之所以存在构造方法,是因为子类再new的过程会调用父类的构造方法,所以存在是必要的
  2. 抽象类特性
    可以单继承抽象类、具体类。具体类继承抽象类的话,要么实现其抽象方法,要么声明为抽象类。通过对抽象类类成员的分析,抽象类除了多了一个抽象方法外,其他的与一般类无异。抽象类可以没有抽象成员,也可以全是抽象成员。
  • 接口
  1. 类成员
    属性:不能含有一般属性,只能是public static final,可以不写,但换成其他会报错
    方法:不能含有一般方法,只能是public abstract,可以不写,但不能换成其他
    块:不能有,块本身就是没有修饰符、返回值的特殊方法,是具体的
    构造方法:没有。因为在属性是静态常量、方法没有方法体,块也没有,这些东西直接保存在方法区就好。堆中创建对象是无意义的,接口不能创建对象。
  2. 接口特性
    接口不能继承别的类
    抽象类可以多实现接口,抽象列实现接口的情况比如Servlet接口和GenericServlet的关系。
    具体类可以多实现接口
    接口多继承接口
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值