java静态变量加载顺序_内部类为什么不能有静态

java静态变量加载顺序_内部类为什么不能有静态静态内部类加载顺序我们先来区分一下两个概念:类加载、加载。类加载的过程包括加载,初始化,验证,解析,准备,初始化等五个过程。加载是类加载的一部分。区分完这两个概念之后我们再来看下面的问题。我们声明一个类,这个类有个内部静态类。还有主函数,当我们启动程序之后,运行javaapplication……

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

                                             静态内部类加载顺序

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

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

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

我们声明一个类,这个类有个内部静态类。还有主函数,当我们启动程序之后,运行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;
	}

}

java静态变量加载顺序_内部类为什么不能有静态

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

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

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

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

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

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

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

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

java静态变量加载顺序_内部类为什么不能有静态

或者有隐式的调用我们类的方法。为什么我们的外部类没有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());
	}

}

上面程序的运行结果:

java静态变量加载顺序_内部类为什么不能有静态

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

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

也是只生成一个对象。

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183637.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 串口打印是什么意思_串口无法启动 代码10

    串口打印是什么意思_串口无法启动 代码10DM36xinitializationpassed!TIUBLVersion:1.50BootingCatalogBootLoader         //启动目录BootLoader                           BootMode=NAND       

  • mysql:Java通过驱动包(jar包)连接MySQL数据库—步骤总结及验证

    mysql:Java通过驱动包(jar包)连接MySQL数据库—步骤总结及验证Java如何使用JDBC连接MySQL数据库一、下载驱动包Java连接MySQL需要驱动包,官网下载地址为MySQL驱动包官网下载还是建议大家下载以前的版本这是我选择的版本解压后得到jar库文件1.在工程目录中创建lib文件夹,将下载好的JDBC放到该文件夹下,如下图所示:2.右键工程名,点击最下方—Propertise,在javabuildpath中的…

  • 上海市高校计算机考试准考证

    上海市高校计算机考试准考证大家好啊,距离22考研初试仅剩26天,现在这个时候,大家除了对知识点进行查缺补漏之外,也得关注一些关于考前的准备工作,还有考场的注意事项哦!因为地区的不同,考点的不同,监考老师的不同,考试的要求和规定也会有差异哦,所以大家在拿到准考证之后,一定要仔细查看考试考点的要求~#考研倒计时#打开腾讯新闻,查看更多图片>1、可不可以戴手表、手环?如果要戴手表,那必须是没有记忆及计算功能的,也就是机械表,手环算电子产品大概率是不可以带的,在进考场之前可以询问一下监考老师,确认一下是否可以带

  • 基于 CAS 无锁实现的 Disruptor.NET 居然慢于 BlockingCollection,是真的吗?

    基于 CAS 无锁实现的 Disruptor.NET 居然慢于 BlockingCollection,是真的吗?

    2021年11月24日
  • 我国无线2.4g及5g信道-个人笔记

    我国无线2.4g及5g信道-个人笔记中国无线信道规划2.4G频段(2.412GHZ-2.472GHZ)信道中心频率频率范围01   2412  2401-242302   2417  2406-242803   2422  2411-243304   2427  2416-243805   2432  2421-244306   2437  2426-244807   2442  2431-245308   2447  2426-244809   2452  2441-246310   2457  24

  • .Net培训班课程体系

    .Net培训班课程体系.Net培训第一部分:.Net基础

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号