Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

时间:2023-02-11 20:27:18

直接上代码:

代码1:

public class ConstroctTest {
private static ConstroctTest test = new ConstroctTest();
//静态变量sta1 未赋予初始值
public static int sta1;
//静态变量sta1 赋予初始值20
public static int sta2 = 20;
//构造方法中对于静态变量赋值
private ConstroctTest() {
sta1 ++ ;
sta2 ++ ;
}
public static void main(String[] args) {
System.out.println(ConstroctTest.sta1);
System.out.println(ConstroctTest.sta2);
}
}

结果:

1
20

代码2:

public class ConstroctTest {
//静态变量sta1 未赋予初始值
public static int sta1;
//静态变量sta1 赋予初始值20
public static int sta2 = 20;
private static ConstroctTest test = new ConstroctTest();
//构造方法中对于静态变量赋值
private ConstroctTest() {
sta1 ++ ;
sta2 ++ ;
}
public static void main(String[] args) {
System.out.println(ConstroctTest.sta1);
System.out.println(ConstroctTest.sta2);
}
}

结果:

1
21

结果分析:

1. 按照静态变量的顺序,初始化各静态变量。(给变量赋予默认值)

2. 按照顺序,赋予静态变量的初始值。

3. 以上结果在于:类静态变量的位置,决定着通过构造方法给sta1 与 sta2 赋予的值是否有效。

4. 在代码一中,先对于sta2 执行了 sta2 ++ 操作。而后给sta2 赋予静态变量值。(只因为顺序问题)

代码3:

public class ConstroctTest {
//静态变量sta1 未赋予初始值
public static int sta1;
//静态变量sta1 赋予初始值20
public static int sta2 = 20;
private static ConstroctTest test = new ConstroctTest();
//构造方法中对于静态变量赋值
private ConstroctTest() {
System.out.println("123456");
sta1 ++ ;
sta2 ++ ;
}
public static void main(String[] args) {
System.out.println(ConstroctTest.sta1);
System.out.println(ConstroctTest.sta2);
System.out.println(ConstroctTest.sta1);
System.out.println(ConstroctTest.sta1);
}
}

结果:

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

结果分析:

1. 从结果可以看出,Java的静态变量,只是在类第一次加载,初始化的时候执行。

2. 类变量不依赖类的实例,类变量只在初始化时候在栈内存中被分配一次空间,无论类的实例被创建几次,都不再为类变量分配空间。

3. 可以看出 ,类变量的执行与初始化,与实例对象没有关系。

代码4:

public class Test{
public static void main(String[] args){
Child ch = new Child();
}
}
class Parent{
static String name1 = "hello";
static{
System.out.println("Parent static block");
}
public Parent(){
System.out.println("Parent construct block");
}
}
class Child extends Parent{
static String name2 = "hello";
static{
System.out.println("Child static block");
}
public Child(){
System.out.println("Child construct block");
}
}

结果:

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

结果分析:

1. 明先初始化父类的静态属性在执行自己的静态属性,再是父类的构造方法再是自己的构造方法。

2. 实例化 Child 类。第一要初始化类Child ,因为Child拥有父类(会判断父类是否初始化),类的初始化只有一次。。初始化类(就是按照顺序加载静态变量与静态方法)。

3. 初始化Child后。开始实例化Child ,因为拥有父类,所以调用构造方法之前会调用父类的默认构造方法。

代码5:

public class Animal {
private static int k;
static{
System.out.println("父类的静态方法");
}
{
System.out.println("执行父类的构造代码块");
}
public Animal(){
System.out.println("执行父类的构造方法");
}
public static void main(String[] args) {
System.out.println(Animal.k);
}
}

  运行结果:

父类的静态方法
0

结果分析:
1. 构造代码块与构造方法对于类的加载 没有关系。

代码6:

public class Animal {
private static int k;
{
System.out.println("执行父类的构造代码块");
}
static{
System.out.println("父类的静态方法");
}
public Animal(){
System.out.println("执行父类的构造方法");
}
public static void main(String[] args) {
Animal animal1 = new Animal();
Animal animal2 = new Animal();
}
}

结果:

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

结果分析:

1. 构造代码块至于构造方法相关,随着构造方法的执行而执行。

代码7:

public class Cat {
private static int a;
private static int b = 1000;
static{
a = 100;
b = 200;
} public static void main(String[] args) {
System.out.println(Cat.a);
System.out.println(Cat.b);
}
}

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

结果分析:

1. 可以把静代码块中的内容 看做是赋予操作。

2.  当静态代码块在a,b前面。此时输出的结果是100 1000

代码8:

package com.fande.amazon.ws.member.rs;
class A {
static {
System.out.println("A的静态块");
}
private static String staticStr = getStaticStr();
private String str = getStr();
{
System.out.println("A的实例块");
}
public A() {
System.out.println("A的构造方法");
}
private static String getStaticStr() {
System.out.println("A的静态属性初始化");
return null;
}
private String getStr() {
System.out.println("A的实例属性初始化");
return null;
}
public static void main(String[] args) {
new B();
new B();
} }
class B extends A{
private static String staticStr = getStaticStr();
static {
System.out.println("B的静态块");
}
{
System.out.println("B的实例块");
}
public B() {
System.out.println("B的构造方法");
}
private String str = getStr();
private static String getStaticStr() {
System.out.println("B的静态属性初始化");
return null;
}
private String getStr() {
System.out.println("B的实例属性初始化");
return null;
}
}

通过上面的分析,结果应该很明确了:

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

总结:

由此可见,实例化子类的时候,若此类未被加载过,首先加载是父类的类对象,然后加载子类的类对象,接着实例化父类,最后实例化子类,若此类被加载过,不再加载父类和子类的类对象。

接下来是加载顺序,当加载类对象时,首先初始化静态属性,然后执行静态块;当实例化对象时,首先执行构造块(直接写在类中的代码块),然后执行构造方法。至于各静态块和静态属性初始化哪个些执行,是按代码的先后顺序。属性、构造块(也就是上面的实例块)、构造方法之间的执行顺序(但构造块一定会在构造方法前执行),也是按代码的先后顺序。

参考:

http://www.cnblogs.com/maowh/p/3729971.html

http://blog.sina.com.cn/s/blog_68117d6d0102uzbq.html

Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序的更多相关文章

  1. java中静态变量,静态代码块,静态方法,实例变量,匿名代码块等的加载顺序

    转自:http://blog.csdn.net/mrzhoug/article/details/51581994 一.在Java中,使用”{}”括起来的代码称为代码块,代码块可以分为以下四种: 1.普 ...

  2. Java代码执行顺序(静态变量,非静态变量,静态代码块,代码块,构造函数)加载顺序

    //据说这是一道阿里巴巴面试题,先以这道题为例分析下 public class Text { public static int k = 0; public static Text t1 = new ...

  3. (转)面试题--JAVA中静态块、静态变量加载顺序详解

    public class Test { //1.第一步,准备加载类 public static void main(String[] args) { new Test(); //4.第四步,new一个 ...

  4. Java类加载机制(加载、验证、准备、解析、初始化)

    如下图所示,Java的类加载机制主要分为三个部分,分别为加载.链接.初始化.其中链接又分为三个小部分--验证.准备.解析. 加载--在经过对Java代码进行编译后,JVM将Java类编译后的二进制文件 ...

  5. 由阿里巴巴笔试题看java加载顺序

    一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...

  6. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  7. Java中静态变量、静态代码块、非静态代码块以及静态方法的加载顺序

    在研究单例设计模式的时候,用到了静态变量和静态方法的内容,出于兴趣,这里简单了解一下这四个模块在类初始化的时候的加载顺序. 经过研究发现,它们的加载顺序为: 1.非静态代码块 2.静态变量或者静态代码 ...

  8. 编写Java程序,观察类启动时静态代码块和main()的执行顺序

    返回本章节 返回作业目录 需求说明: 观察类启动时静态代码块和main()的执行顺序 在Book类中定义静态代码块. 在Book中分别定义一个普通实例方法和静态方法. 在Book类的静态代码块中调用静 ...

  9. Java 类加载机制 ClassLoader Class.forName 内存管理 垃圾回收GC

    [转载] :http://my.oschina.net/rouchongzi/blog/171046 Java之类加载机制 类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指 ...

随机推荐

  1. IOS设计模式-备忘录模式

    内容大纲 如何存储记录 备忘录模式的基本原理 使用备忘录模式 优化存储方案 恢复UIView的状态 1.如何存储记录 在存储记录时,第一步我们需要用一把钥匙去打开一把锁.第二步,当我们打开锁之后就会有 ...

  2. java左移右移运算符

    http://blog.csdn.net/dandanteng/article/details/7433531 首先要明白一点,这里面所有的操作都是针对存储在计算机中中二进制的操作,那么就要知道,正数 ...

  3. openwrt使用3G上网卡

    尊敬的大大.感谢你抽空指导我 我的设备是db120 mu350 和广东无限卡 版本是OpenWrt Backfire 10.03.336 DIY full 一.        没有安装到kmod-us ...

  4. MySQL 性能优化的最佳20多条经验分享(二)(转)

    11. 尽可能的使用 NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL.这看起来好像有点争议,请往下看. 首先,问问你自己"Empt ...

  5. python中__del__使用方法

    创建对象后,python解释器默认调用__init__()方法.当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法.在python中,对于开发者来说很少会直接销 ...

  6. spring-boot-maven-plugin 安装本地jar 包

    本地使用nexus 进行maven仓库管理.项目deploy 引入之后,总是找不到jar中定义的class或者配置文件等. 从截图上可以看到虽然class文件是有的,但是引用的时候却是找不到的. Sp ...

  7. vscode 最新中文设置

    切换中文 首先看商店里有没有chinese language那个中文插件. 在ctrl + shift +p 搜索configure language,然后配置locale如下即可配置中文.

  8. Java过滤掉字符串中的html标签、style标签、script标签

    使用正则表达式 import java.util.regex.Matcher; import java.util.regex.Pattern; public class HTMLSpirit{ pub ...

  9. Spring Data JPA使用keywords关键字实现CAST函数

    对不起,经过几天几夜的使用的研究得出这种方式是无法实现的,在查询上的关键字只有这些: https://docs.spring.io/spring-data/jpa/docs/2.1.x/referen ...

  10. idea 设置不合并空目录或者包的方法

    不勾选此项即可