java静态内部类加载顺序

                                             静态内部类加载顺序

我们先来区分一下两个概念:类加载加载

类加载的过程包括加载,验证,解析,准备,初始化等五个过程。加载是类加载的一部分。

区分完这两个概念之后我们再来看下面的问题。

我们声明一个类,这个类有个内部静态类。还有主函数,当我们启动程序之后,运行java application程序。

运行结果是什么呢?

下面看个代码实现的例子:

package Test;

public class OuterClass {
	static {
		System.out.println("加载外部类");
	}
	static class InnerClass{
		public InnerClass() {}
		static {
			System.out.println("加载内部类");
		}
		static void innerMethod() {
			System.out.println("内部类的静态方法");
		}
		static int a;
	}

	public static void main(String[] args) {
		OuterClass out=new OuterClass();
		System.out.println("=============");
//		OuterClass.InnerClass.a=1;
	}

}

外部类的静态代码块执行了。内部类的静态代码块没有执行在外部类执行静态代码块之后执行,是因为内部类没有加载么?

其实不是这样的,一旦程序运行,所有该类涉及的类(包括内部类和从其他包导入的类)都会在类加载的过程中加载

内存,因为在整个程序运行的过程中类加载只会发生一次,一旦某个类没有被加载,那么将不能再使用这个类。

注意我标出来的加载,这里是指在类加载过程中的加载,但是我们可以在网上了解或者在书上得知,只有当某个类

初始化之后,才会调用类的静态代码块。才会执行对应的。那么什么时候执行类加载过程中的类初始化呢?

只有当我们有对类的引用的时候,才会将类初始化。

比如我们new一个非静态类的对象,或者对某个静态类的成员(包括成员方法和域)或者调用有访问的时候

如果我们把最后一行的注释去掉,就会执行内部静态类的静态代码块(static{})。

或者有隐式的调用我们类的方法。为什么我们的外部类没有new的时候还会执行他的静态代码块呢?

是不是忘了还有个主函数在执行,这时候是调用了类的方法的,所以会初始化这个外部类。执行外部类的静态代码块。

关于静态代码块,代码块,类的构造函数执行顺序问题不态理解的同学可以看看我的博客:

Java面试题 类的构造函数的执行顺序问题

注意:内部静态类不会自动初始化,只有调用静态内部类的方法,静态域,或者构造方法的时候才会加载静态内部类。

利用这种特点我们可以实现一个单例模式

package Test;

public class Single {
	
	private Single() {}
	
	static class SingleHolder {
		
		private static final Single instance=new Single(); 
		
	}
	public static Single getinstance() {
		return SingleHolder.instance;
	}

	public static void main(String[] args) {
		
		Single a=Single.getinstance();
		Single b=Single.getinstance();
		Single c=Single.getinstance();
		System.out.println(a.toString());
		System.out.println(b.toString());
		System.out.println(c.toString());
	}

}

上面程序的运行结果:

当我们用的构造方法声明为private的时候,代表这个类只能被自己调用,就算同包下的类也不能实例化。

这并不是构造函数只会被调用一次,并且保证只会实例化一次类的原因。如果你把上面的构造函数变成public,

也是只生成一个对象。

上面的例子是说这个外部类的对象被内部类当成内部类的静态final域,所以只会有一个。

  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Java的类加载机制是指将类的字节码文件加载到内存中,并在运行时将其转换为可执行的代码的过程。Java的类加载机制遵循了一定的规则和顺序,可以分为以下几个步骤: 1. 加载:类加载的第一步是加载,即将类的字节码文件加载到内存中。Java的类加载器负责从文件系统、网络或其他来源加载类的字节码文件。加载过程中会进行词法和语法的验证,确保字节码文件的正确性。 2. 链接:类加载的第二步是链接,即将已经加载的类与其他类或者符号进行关联。链接分为三个阶段: - 验证:验证阶段确保类的字节码文件符合Java虚拟机规范,包括检查文件格式、语义验证等。 - 准备:准备阶段为静态变量分配内存空间,并设置默认初始值。 - 解析:解析阶段将符号引用转换为直接引用,例如将类或者方法的符号引用解析为对应的内存地址。 3. 初始化:初始化是类加载的最后一步,在此步骤中会执行类的初始化代码,对静态变量进行赋值和执行静态代码块。类的初始化是在首次使用该类时触发的,或者通过反射方式调用`Class.forName()`方法来强制初始化。 Java的类加载机制是动态的,可以根据需要加载和卸载类,它还支持类的继承、接口实现、内部类等特性。类加载机制是Java语言的重要特性之一,它为Java提供了强大的动态性和灵活性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值