java基础-静态,非静态(构造)代码块,类加载
static block and non-static block(constructor block)
想来想去,先来一题比较好
public class Foo {
public static void main(String[] args) {
Baz.testAsserts();
Baz.testAsserts();
// Will execute after Baz is initialized.
}
}
class Bar {
static {
Baz.testAsserts();
// Will execute before Baz is initialized!
}
}
class Baz extends Bar {
static int x = 1;
static void testAsserts() {
System.out.println("x is " + x);
x=x+2;
}
}
- 输出结果
x is 0
x is 1
x is 3
- 分析
- Invoking Baz.testAsserts() cause Baz to be initialized
- default value int x=0;
- Before Baz initialize , Bar must be initialized
- Bar's static initializer again invoking Baz.testAsserts()
- so x is 0 , then x+2 , x=2
- go on initializing Baz , init x = 1;
- Invoking Baz.testAsserts() x = 1 , so x is 1;
Java类初始化顺序
父类静态变量 ——>父类静态代码块——>子类静态代码块——>父类非静态变量 ——>
父类非静态代码块——>父类构造函数 ——>子类非静态变量——>子类非静态代码块——>
子类构造函数
非静态代码块 non-static block(constructor block)
class A {
int x ;
//block num 1
{
x = 1;
System.out.println("block num 1, x is " + x);
}
A() {
x = 3;
System.out.println("constructor block x is " + x);
}
//block num 2
{
x = 2;
System.out.println("block num 2, x is " + x);
}
}
public class Non_staticBlock {
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====first time instantiate ====" + newLine);
new A();
System.out.println(" \n====second time instantiate ====" + newLine);
new A();
}
}
- 输出结果、顺序
====first time instantiate ====
block num 1, x is 1
block num 2, x is 2
constructor x is 3====second time instantiate ====
block num 1, x is 1
block num 2, x is 2
constructor x is 3
- 非静态代码块被java编译器拷贝到了构造块内,所以称为"constructor block"也是可以的,所以每次 new 构造函数也都执行
- .class 文件如下, 非静态代码块被java编译器拷贝到了构造块内.
class A {
int x = 1;
A() {
System.out.println("block num 1, x is " + this.x);
this.x = 2;
System.out.println("block num 2, x is " + this.x);
this.x = 3;
System.out.println("constructor x is " + this.x);
}
}
静态代码块 static block
class AA {
AA() {
x = 3;
System.out.println("constructor x is " + x);
}
static int x = 1;
//block num 1
static {
System.out.println("static block num 1 , x is " + x);
}
//block num 2
static {
x = 2;
System.out.println("static block num 2 , x is " + x);
}
static void print() {
System.out.println("static method");
}
}
public class StaticBlock {
static {
System.out.println("==== first ====");
}
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====AA class init ====" + newLine);
// class init
AA.print();
System.out.println(" \n====fisrt time instantiate AA====" + newLine);
new AA();
System.out.println(" \n====sencond time instantiate AA====" + newLine);
new AA();
}
}
- 输出结果、顺序
==== first ====
====AA class init ====static block num 1 , x is 1
static block num 2 , x is 2
static method
==== first time instantiate AA ====constructor x is 3
==== second time instantiate AA ====
constructor x is 3
- 由于JVM在加载类时会执行静态代码块,且只会执行一次. 本例静态引用
AA.print();
触发类初始化 - 静态代码块先于主方法执行,本例优先打印
first
- 更多内容搜索jvm类加载
- .class 文件如下
class AA {
static int x = 1;
AA() {
x = 3;
System.out.println("constructor x is " + x);
}
static void print() {
System.out.println("static method");
}
static {
System.out.println("static block num 1 , x is " + x);
x = 2;
System.out.println("static block num 2 , x is " + x);
}
}
联合看一下
class AAA {
int x;
//block num 1
{
x = 1;
System.out.println("non-static block num 1 x is " + x);
}
AAA() {
x = 3;
System.out.println("constructor x is " + x);
}
//block num 2
{
x = 2;
System.out.println("non-static block num 2 x is " + x);
}
// The static block only gets called once,when the class itself is initialized,
// no matter how many objects of that type you create
static {
System.out.println("static block");
}
//Gets called every time an instance of the class is constructed.
//the non-static block is actually copied by the Java compiler into every constructor the class has (source).
//So it is still the constructor's job to initialize fields.
//to understand "actually " , find the result in the .class file of A.class
{
System.out.println("non-static block");
}
}
public class BlockSample {
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====first time instantiate AAA ====" + newLine);
new AAA();
System.out.println(" \n====second time instantiate AAA ====" + newLine);
new AAA();
}
}
- 输出结果、顺序
====first time instantiate AAA ====
static block
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3====second time instantiate AAA ====
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3
- .class 文件
class AAA {
int x = 1;
AAA() {
System.out.println("non-static block num 1 x is " + this.x);
this.x = 2;
System.out.println("non-static block num 2 x is " + this.x);
System.out.println("non-static block");
this.x = 3;
System.out.println("constructor x is " + this.x);
}
static {
System.out.println("static block");
}
}
java基础-静态,非静态(构造)代码块,类加载的更多相关文章
- java基础8 构造函数和构造代码块
一.构造函数 1 构造函数的作用 给对应的对象进行初始化. 2 构造函数的格式 修饰符 函数名(形式参数){ //函数名就是类名 函数体 } 举例说明: class Perosn{ private i ...
- 黑马程序员——JAVA基础之构造函数,构造代码块
------- android培训.java培训.期待与您交流! ---------- 构造函数特点: 1. 函数名与类名相同 2. 不用定义返回值类型 3. 不可以写return语句 构造函数 ...
- java静态代码块、静态方法、静态变量、构造代码块、普通代码块
一.静态代码块 1.在java类中(方法中不能存在静态代码块)使用static关键字和{}声明的代码块: public class CodeBlock{ static{ System.out.prin ...
- Java 基础 面向对象之关键字内部类代码块修饰符
final final概念 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后 ...
- 【Java基础】继承中的代码块和构造方法的执行顺序探索
本文讲述有关一个类的静态代码块,构造代码块,构造方法的执行流程问题.首先来看一个例子 /** * Created by lili on 15/10/19. */ class Person{ stati ...
- java基础-表达式,语句和代码块
浏览以下内容前,请点击并阅读 声明 表达式 表达式由变量,操作符和方法调用组成,表达式的返回值类型由表达式中的元素(如操作符,变量等)决定如: cadence = 0 上述代码将返回一个int类型的值 ...
- Java类中代码的执行顺序 静态代码块>构造代码块>构造方法
一:静态代码块 注意是代码块,不是静态函数.函数要调用才执行,代码块加载就执行,一般是静态变量的声明与初始化.被static修饰的代码块(赋值.输出操作等).类中静态语句块仅在类加载时被执行一次 如 ...
- 【Java基础】2、Java中普通代码块,构造代码块,静态代码块区别及代码示例
Java中普通代码块,构造代码块,静态代码块区别及代码示例.Java中普通代码块,构造代码块,静态代码块区别及代码示例 执行顺序:静态代码块>静态方法(main方法)>构造代码块>构 ...
- java基础之静态代码块,局部代码块,构造代码块区别。
java中有几种常见的代码块,那怎样区别他们呢? 这里就这些问题,浅谈下我个人的理解. 1.局部代码块 局部代码块,又叫普通代码块.它是作用在方法中的代码块.例如: public void show( ...
随机推荐
- 【后缀数组】洛谷P3809模板题
题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...
- 【MySQL】计算 TPS,QPS 的方式
在做db基准测试的时候,qps,tps 是衡量数据库性能的关键指标.本文比较了网上的两种计算方式.先来了解一下相关概念. 概念介绍: QPS:Queries Per Second 查 ...
- better-scroll不能滚动之 滚动监听-左右联动
滚动监听 better-scroll 无法滚动的分析,直接翻到最后,看问题汇总,希望能帮助你解决. 借用一下人家这个好看的项目图片,做一个解释.左边的内容会跟右边的内容一起关联,点击左边的菜单,右边会 ...
- 关于setTimeout的面试题
于地铁上看了一篇帖子,关于setTimeout的面试题,觉得见得多,记录,以学习之. 我们都知道,这样的一个例子: for ( var i = 0;i<5; i++) { console.log ...
- [已解决]import pymssql ImportError: libsybdb.so.5
在python3.6的环境下安装pymssql安装包,运行程序时报错:import pymssql ImportError: libsybdb.so.5 在网上搜索了一大圈很多都是讲文件存在但是没有添 ...
- cs231n spring 2017 lecture15 Efficient Methods and Hardware for Deep Learning 听课笔记
1. 深度学习面临的问题: 1)模型越来越大,很难在移动端部署,也很难网络更新. 2)训练时间越来越长,限制了研究人员的产量. 3)耗能太多,硬件成本昂贵. 解决的方法:联合设计算法和硬件. 计算硬件 ...
- HDU 2502 月之数(二进制,规律)
月之数 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- COGS 68. [NOIP2005] 采药【01背包复习】
68. [NOIP2005] 采药 ★ 输入文件:medic.in 输出文件:medic.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 辰辰是个天资聪颖的孩 ...
- ACM中常见错误对应表
因为经常写错题,找了个这个看看... 传送门:http://www.cnblogs.com/ZouCharming/p/3868844.html 我太垃圾了... 我出现过的错误: Wrong Ans ...
- Trees on the level(指针法和非指针法构造二叉树)
Trees on the level Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...