什么是代码块?
在Java中,使用”{}”括起来的代码称为代码块,代码块可以分为以下四种:
1.普通代码块:就是类中方法的方法体 直接在一个方法中出现的{}就称为普通代码块。例子程序如下:
public void xxx(){
//code
}
2.构造代码块:用{}裹起来的代码片段,直接在类中定义的没有加static关键字的代码块{}称为构造代码块。
构造块在创建对象时会被调用,每次创建对象时都会被调用,并且优先于类构造函数执行。
例子程序如下:
public class ConstructBlock{
public ConstructBlock(){
System.out.println("========这是构造方法=========");
}
//这是构造代码块,而且在new对象时,构造代码块优先构造方法执行
{
System.out.println("=========这是构造块!=========");
}
3.静态块:用static{}裹起来的代码片段,使用static关键字声明的代码块称为静态代码块。
只会被执行一次(第一次加载此类时执行,比如说用Class.forName("")加载类时就会执行( static block),静态块优先于构造块执行。 ,静态块的主要目的是用来为静态属性初始化,
例子程序如下:
static{
//code
}
4.同步代码块:使用synchronized(obj){}裹起来的代码块。
在多线程环境下,对共享数据进行读写操作是需要互斥进行的,否则会导致数据的不一致性。
常见的是synchronized用来修饰方法,其语义是任何线程进入synchronized需要先取得对象锁。如果被占用了,则阻塞,实现了互斥访问共享资源。而synchronized也是有代价的。同步代码块主要出现在多线程中。
一个常见的场景是,一个冗长的方法中,其实只有一小段代码需要访问共享资源,这时使用同步块,就只将这小段代码
裹在synchronized block,既能够实现同步访问,也能够减少同步引入的开销。
synchronized(obj){
//code
}
/*
* 几大原则
* 一、静态成员变量(Static)
* 1、静态成员变量为类变量,所有对象共享同一内存空间
* 2、静态成员变量的声明和定义仅在首次加载类时执行一次
* 3、首次加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的附右值
* 二、静态初始块
* 1、静态初始化块仅在首次加载类时执行一次
* ······多个静态成员变量与静态始化快参照出现顺序先后执行······
* 三、实例成员变量
* 1、实例成员变量定义在每次实例化对象时在构造函数之前执行
* 四、构造初始化块
* 1、构造初始化块在每次实例化对象时在构造函数之前执行
* ······多个实例成员变量与构造初始化块参照出现顺序先后执行······
* 总结:总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行
* 1、按照出现顺序先后执行静态成员变量定义与静态初始化块
* 2、按照出现顺序先后执行实例成员变量定义与构造初始化块
* 3、执行构造函数
* 再次实例化对象时只执行第2、3步即可
*
* ············实例成员变量与定义与初始化块先于构造函数执行·········
* 五、当涉及到继承时,按照如下顺序执行
* 1、执行父类的静态成员变量定义与静态初始化块,执行子类的静态成员变量定义与静态初始化块
* 2、执行父类的非静态成员变量定义与构造初始化块,执行父类构造方法
* 3、执行子类的非静态成员变量定义与构造初始化块,执行子类构造方法
* 另:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法
*/
package com.xjf.java.training;
public class StaticBlock {
public static void main(String[] args) {
int i = 1;
switch(i) {
case 0:
new Super();
new Super();
break;
case 1:
Super s = new Sub();
break;
case 2 :
Client c1 = new Client();
System.out.println("c.i1 = " + c1.i1);//2
System.out.println("c.i2 = " + c1.i2);//3
break;
}
/* 对i=2时的解释
* 为什么是2和3呢?
* 其实代码的执行顺序是这样的:在初始化c1的时候首先加载类
* 定义静态变量t1,i1,i2并赋初值null,0,0
* 然后计算右值表达式new Client(),准备将此对象赋给静态成员变量c
* 然而上步中静态成员变量已定义,直接执行c的构造函数即可
* 这样i1++,i2++被执行,i1,i2都变为1
* 继续执行到int i1;没有赋值语句, i1,i2的值仍然是1
* 继续执行到int i2 = 2时i2被赋值2,即i1 = 1,i2 = 2
* 继续执行到c1的构造函数,i1,i2再执行++,此时i1 = 2,i2 = 3
* 输出i1,i2,结果就是:c1.i1 = 2,c1.i2 = 3
* 通过上面的代码我们可以认为系统默认值的给予比通过等号的赋予先执行。
*/
}
}
class Super {
public Super() {
System.out.println("construct Super");
function();
System.out.println();
}
private int superInstanceVar = getSuperInstanceVar();
{
System.out.println(" contruct block in Super");
}
static {
System.out.println("static block in Super");
}
private static int superStaticVar = getSuperStaticVar();
static int getSuperStaticVar() {
System.out.println("initial static int superStaticVar");
System.out.println();
return 5;
}
static int getSuperInstanceVar() {
// TODO Auto-generated method stub
System.out.println("initial int superInstanceVar");
return 10;
}
public void function() {
System.out.println("super.function()");
}
}
class Sub extends Super{
public Sub() {
System.out.println("construct Sub");
super.function();
function();
}
{
System.out.println("contruct block in Sub");
}
private int subInstanceVar = getSubInstanceVar();
static {
System.out.println("static block in Sub");
}
private static int subStaticVar = getSubStaticVar();
static int getSubStaticVar() {
System.out.println("initial static int subStaticVar");
System.out.println();
return 5;
}
static int getSubInstanceVar() {
System.out.println("initial int subInstanceVar");
return 10;
}
public void function() {
System.out.println("sub.function() subInstanceVar=" + subInstanceVar);
}
}
class Client{
private static Client c = new Client();
public static int i1;
public static int i2 = 2;
public Client(){
i1++;
i2++;
}
}
/*
i=0时输出:
static block in Super--父类中静态代码块
initial static int superStaticVar--父类中静态方法显示初始化父类静态变量
initial int superInstanceVar--显示初始化父类实例变量
contruct block in Super--执行父类中的构造代码块
construct Super--执行父类构造方法
super.function()--调用父类方法
initial int superInstanceVar--显示初始化父类实例变量
contruct block in Super--执行父类中的构造代码块
construct Super--执行父类构造方法
super.function()--调用父类的function方法
---------------------------
i=1时输出:
static block in Super--父类中静态代码块
initial static int superStaticVar--父类中静态方法显示初始化父类静态变量
static block in Sub--显示初始化子类代码块
initial static int subStaticVar--显示初始化子类静态变量
initial int superInstanceVar-显示初始化父类实例变量
contruct block in Super--执行父类中的构造代码块
construct Super--执行父类构造方法
sub.function() subInstanceVar=0--父类调用子类复写的function方法,这里出现多态,此时子类中复写的function访问的是子类的subInstanceVar,
由于在父类初始化时子类还没有初始化,所以此时的值为隐式初始化的值即:默认值
contruct block in Sub--执行子类中的构造代码块
initial int subInstanceVar-显示初始化子类实例变量
construct Sub--执行子类构造方法
super.function()--子类调用父类function方法
sub.function() subInstanceVar=10--调用复写父类中的function方法
*/
分享到:
相关推荐
这个压缩包文件“JavaSE常用知识代码实现”显然包含了关于JavaSE的一些常见概念、数据结构、算法以及编程技巧的代码示例。下面将详细阐述JavaSE中的重要知识点。 1. **基础语法**:Java是一门面向对象的语言,其...
1. **静态代码块**:`static`关键字还可以用于创建静态初始化块,这部分代码在类加载时执行,且仅执行一次。例如: ```java public class StaticTest4 { public static void main(String[] args) { P p = new P...
17.1.2 JavaSE 5.0中固定尺寸线程池的基本知识 374 17.1.3 自定义尺寸固定线程池的使用 375 17.1.4 单任务线程池的使用 377 17.1.5 可变尺寸线程池的使用 378 17.1.6 延迟线程池的使用 380 17.1.7 使用...
JavaSE基础是学习Java编程的重要部分,涵盖了标识符、关键字、字面量、数据类型、类型转换、修饰符、代码块、方法重载、this关键字等多个核心概念。 首先,标识符是程序中用来命名类、方法、变量等的符号,遵循特定...
局部变量通常在方法或代码块中声明,其生命周期随方法或代码块的调用结束而终止。类变量则是所有实例共享的变量,通常使用`static`关键字声明。 **示例代码分析:** ```java public class Var { static int a = 3;...
通过`public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }`了解基本的语法结构,包括类、主方法以及输出语句。 3. **数据类型**:Java有两大类数据类型...
什么是面向对象、如何定义类、如何定义对象、成员变量、局部变量、静态变量、匿名对象、Math.randon()/this/static 代码块(局部代码块、构造代码块、静态代码块、同步代码块) 、java内存结构
- **分隔符**:如分号用于结束语句,大括号用于定义代码块等。 ##### 2.2 基本数据类型 Java支持八种基本数据类型,包括四种整数类型(byte、short、int、long)、两种浮点类型(float、double)、一种字符类型...
static 修饰符可以修饰变量、方法和代码块。静态变量属于类的,使用类名来访问,非静态变量是属于对象的,必须使用对象来访问。静态变量在加载类的过程中为静态变量分配内存,实例变量在创建对象时分配内存。因此,...
- **大括号({}):** 定义代码块。 - **双引号("")** 和 **单引号(''):** 分别用于字符串和字符字面量。 **3.3 命名规则** - 变量和方法名应采用小驼峰命名法。 - 类名应采用大驼峰命名法。 - 常量全大写,单词间...
### JavaSE复习提纲知识点详解 ...- `static`修饰的代码块在类加载时执行。 通过以上知识点的梳理,我们可以清晰地了解到JavaSE的基础语法和核心概念,这对于进一步深入学习Java技术栈至关重要。
- 局部变量的生存周期与其所在的代码块一致。 - 类变量和实例变量的生存周期与对象的存在时间相同。 理解这些基础知识对于进一步学习Java编程至关重要。接下来可以深入研究更复杂的概念,如面向对象编程、异常...
3. **函数**:函数是代码的重用机制,Java中的方法允许我们将代码逻辑封装起来,便于调用和复用。 4. **数组**:Java支持一维、二维及多维数组,用于存储同类型的多个数据。数组的操作包括创建、初始化、遍历和访问...
无论`try`块内是否发生异常,`finally`块中的代码都会被执行,主要用于释放资源或进行必要的清理操作。 3. **finalize**:这是`Object`类中的一个方法,被设计用于在垃圾回收器准备释放对象所占用的存储空间前执行...
public static void main(String[] args) { System.out.println("你好,世界!"); } } ``` 在Java中,类(Class)是对象的蓝图,`main`方法是程序的入口点。`System.out.println`用于输出文本到控制台。 接下来...
- **大括号 `{}`**:用于界定代码块或类体的范围,例如方法体或类的成员变量及方法。 - **方括号 `[]`**:表示数组,如 `int[] arr;` 表示一个整型数组。 - **圆括号 `()`**:通常用于方法调用或参数传递,如 `...
4. **方法**:定义功能块,如`public static void main(String[] args)`是程序的入口点。 5. **异常处理**:Java采用try-catch-finally结构处理异常,例如`try { ... } catch (IOException e) { ... } finally { .....
3. **静态初始化块(Static Initialization Blocks)**:这些代码块在类加载时执行,用于初始化静态变量或执行类级别的设置。它们通常用来设置静态变量的初始值,尤其是当初始化过程比较复杂时。 4. **静态内部类...
`static`可以修饰变量、方法和代码块。静态变量是所有实例共享的,也就是说,不论创建多少个对象,它们都指向同一份内存空间。静态方法不依赖于任何实例就可以调用,通常用于工具类或者不需要访问非静态成员的方法。...
顺序语句`if`是条件控制结构,根据条件执行不同代码块。 ### day04 - 顺序语句、循环语句、控制跳转语句 这部分涵盖了流程控制,包括无条件执行的顺序语句,如`for`、`while`、`do...while`循环,以及`break`和`...