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域,所以只会有一个。

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

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

(0)
上一篇 2022年10月10日 上午9:46
下一篇 2022年10月10日 上午9:46


相关推荐

  • 关于图像特征提取

     网上发现一篇不错的文章,是关于图像特征提取的,给自己做的项目有点类似,发出来供大家参考。      特征提取是计算机视觉和图像处理中的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。特征的定义       至今为止特征没有万能和精确的定义。特征的精确定义往往

    2022年4月9日
    44
  • IntelliJ IDEA设置JDK版本

    IntelliJ IDEA设置JDK版本一 背景即使我电脑安装的 JDK 版本是 8 然而在 idea 运行中常常提示 xxjdk1 5 已过时之类的 why 明明是我装的 JDK8 啊二 解决鼠标点击 file gt setting 进入 idea 的设置页面 settings 根据截图操作 懒得写了 最后点击 ok 然后 鼠标点击 file gt ProjectStruc

    2026年3月26日
    1
  • springData Jpa配置文件

    springData Jpa配置文件springDataJp 的配置文件 xmlversion 1 0 encoding UTF 8

    2026年3月18日
    1
  • python strip()方法使用

    python strip()方法使用描述pythonstrip(),用于去除述字符串头尾指定字符(默认为空格或换行符)或字符序列。注意:此方法只能去除头尾的空格或是换行符,不能去除中间的。语法:参数:chars–移除

    2022年7月5日
    24
  • Spring的contextConfigLocation

    Spring的contextConfigLocationspring如何使用多个xml配置文件1,在web.xml中定义contextConfigLocation参数.spring会使用这个参数加载.所有逗号分割的xml.如果没有这个参数,spring默认加载web-inf/applicationContext.xml文件.例如:<context-param><param-name>conte…

    2022年7月14日
    16
  • HTTP和HTTPS的区别,有什么优缺点「建议收藏」

    HTTP和HTTPS的区别,有什么优缺点「建议收藏」http和https:http就是超文本传输协议的缩写,用于从网站服务器传输数据到上网者的本地浏览器的协议https就是在http的基础加上了SSL或者其他的加密方式,所以这就是最主要的区别。原因:因为http在传输的时候是以明文的方式传输数据,这样的话在传输过程中如果被截获就能直接读取信息,所以并不安全,因此需要通过某种方式加密。怎样解决http不安全的问题呢?解决方法就是在http的基础上加上了SSL协议SSL,安全套接字协议,他是靠证书来验证服务端的身份,并在本地

    2022年8月31日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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