Java中的static静态代码块的使用详解

一.与静态方法的比较  

  一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,静态方法在类加载的时候 就已经加载 可以用类名直接调用 比如main方法就必须是静态的 这是程序入口。两者的区别就是:静态代码块是自动执行的; 静态方法是被调用的时候才执行的。

二.静态方法注意事项  

  使用类的静态方法时,注意:

    a.在静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前

不用创建任何对象。

    b.静态方法不能以任何方式引用this和super关键字,因为静态方法在使用前不用创建任何实例对象,当静态方法调用时,this所引用的对象根本没有产生(this关键字只能在方法内部使用,表示对“调用方法的那

个对象”的引用)。

  静态变量是属于整个类的变量而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态,例如: fun() {    static int i=0;//非法。 }

三.程序举例


代码如下:

public class TestStaticCon {
     public static int a = 0;

static {
         a = 10;
         System.out.println("父类的静态代码块在执行a=" + a);
     }

{
         a = 8;
         System.out.println("父类的非静态代码块在执行a=" + a);
     }

public TestStaticCon() {
         this("a在父类带参构造方法中的值:" + TestStaticCon.a); // 调用另外一个构造方法
         System.out.println(a);
         System.out.println("父类无参构造方法在执行a=" + a);
     }

public TestStaticCon(String n) {
         System.out.println(n);
         System.out.println(a);

}

public static void main(String[] args) {
         TestStaticCon tsc = null;
         System.out.println("!!!!!!!!!!!!!!!!!!!!!");
         tsc = new TestStaticCon();
     }
 }

代码如下:

运行结果:
父类的静态代码块在执行a=10
!!!!!!!!!!!!!!!!!!!!!
父类的非静态代码块在执行a=8
a在父类带参构造方法中的值:10
8
8
父类无参构造方法在执行a=8

四.网友提供


代码如下:

public class StaticBlock {

static {
         System.out.println("静态块");
     }
     {
         System.out.println("构造块,在类中定义");
     }

public StaticBlock() {
         System.out.println("构造方法执行");
     }

public static void main(String[] args) {
         new StaticBlock();
         new StaticBlock();
     }

}

代码如下:

静态块
构造块,在类中定义
构造方法执行
构造块,在类中定义
构造方法执行

  结论:静态代码块是在类加载时自动执行的,非静态代码块是在创建对象时自动执行的代码,不创建对象不执行该类的非静态代码块。且执行顺序为静态代码块------非静态代码块----构造函数。

  其中让我疑惑的是“a在父类带参构造方法中的值:10”,我再想那时候为什么不是8,debug了(F11,不能直接设置断点然后运行,那样和直接运行没区别),发现先进入了无参的构造方法,执行了第一条语句并且切换到了另一个构造方法(不管是不是反正第一句都要执行,此时a还是10,非静态代码块还未执行),提示找不到源,不管是不是这条语句都提示了这个警告(不算错误,因为程序继续正常运行),然后运行了非静态代码块,继而从有参的构造方法处继续执行……

(0)

相关推荐

  • Java 中普通代码块,构造代码块,静态代码块区别及代码示例

    Java中普通代码块,构造代码块,静态代码块区别及代码示例 //执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1 普通代码块 //普通代码块:在方法或语句中出现的{}就称为普通代码块.普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定--"先出现先执行" public class CodeBlock01{ public static void main(Strin

  • java中的静态代码块、构造代码块、构造方法详解

    运行下面这段代码,观察其结果: package com.test; public class HelloB extends HelloA { public HelloB() { } { System.out.println("I'm B class"); } static { System.out.println("static B"); } public static void main(String[] args) { new HelloB(); } } cla

  • 关于Java中静态代码块的执行浅析

    前言 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的:需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的, 静态方法在类加载的时候就已经加载,可以用类名直接调用. 比如main方法就必须是静态的,这是程序入口 两者的区别就是: 静态代码块是自动执行的; 静态方法是被调用的时候才执行的. 问题及总结 关于静态代码块其实是面试时老生常谈的问题,虽然面试时问了我也大概知道,但是在用的时候还

  • Java 普通代码块静态代码块执行顺序(实例讲解)

    如下所示: class B { public B() { super(); System.out.println("构造器B"); } { System.out.println("普通的代码块B"); } static{ System.out.println("静态代码块B"); } } public class ClassA extends B { public ClassA() { super(); System.out.println(&q

  • java 代码块与静态代码块加载顺序

    java 代码块与静态代码块加载顺序 public abstract class ClassLoadingTest { public static void main(String[] args) { User user3 = new User(); } } public class User { public static User user= new User("wang",18); public static void userSay(){ System.out.println(

  • 深入浅析Java中普通代码块、构造代码块与静态代码块

    //执行顺序:(优先级从高到低.) 静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1.普通代码块 public static void main(String[] args) { /*普通代码块: *直接定义在在方法或语句中出现"{普通代码的执行语句}"的就称为普通代码块. *普通代码块执行顺序由他们在代码中出现的次序决定--"先出现先执行" * */ { System.out.p

  • Java中的static静态代码块的使用详解

    一.与静态方法的比较 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,静态方法在类加载的时候 就已经加载 可以用类名直接调用 比如main方法就必须是静态的 这是程序入口.两者的区别就是:静态代码块是自动执行的; 静态方法是被调用的时候才执行的. 二.静态方法注意事项 使用类的静态方法时,注意: a.在静态方法里只能直接调用同类中其他的静态成员(包括变量

  • java 中同步方法和同步代码块的区别详解

    java 中同步方法和同步代码块的区别详解 在Java语言中,每一个对象有一把锁.线程可以使用synchronized关键字来获取对象上的锁.synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁). 问题的由来: 看到这样一个面试题: //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized (obj){} } synchronized用于解决同步问

  • 详解java中的四种代码块

    在java中用{}括起来的称为代码块,代码块可分为以下四种: 一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. 3.静态代码块: 用static{}包裹起来的代码片段,只会执行一次.静态代码块优先于构造块执行. 4.同步代码块: 使用synchronized(){}包裹起来的代码块,在多线程环境下,对共享数据的读写操作是需要互斥进行的,否则会导致数据的不一致性.同步代码块需要写在方法中. 二.静态代码块和构造

  • java中synchronized(同步代码块和同步方法)详解及区别

     java中synchronized(同步代码块和同步方法)详解及区别 问题的由来: 看到这样一个面试题: //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized (obj){} } synchronized用于解决同步问题,当有多条线程同时访问共享数据时,如果进行同步,就会发生错误,Java提供的解决方案是:只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他

  • Java中的引用和动态代理的实现详解

    我们知道,动态代理(这里指JDK的动态代理)与静态代理的区别在于,其真实的代理类是动态生成的.但具体是怎么生成,生成的代理类包含了哪些内容,以什么形式存在,它为什么一定要以接口为基础? 如果去看动态代理的源代码(java.lang.reflect.Proxy),会发现其原理很简单(真正二进制类文件的生成是在本地方法中完成,源代码中没有),但其中用到了一个缓冲类java.lang.reflect.WeakCache<ClassLoader,Class<?>[],Class<?>

  • java中的抽象类和接口定义与用法详解

    目录 一.抽象类 1.什么叫抽象类? 2.抽象类的特点: 3.成员特点: 二.接口 1.接口是什么? 2.接口的特点 3.接口的组成成员 4.类与抽象的关系: 5.抽象类与接口的区别: 一.抽象类 1.什么叫抽象类? 例如在生活中我们都把狗和猫归为动物着一类中,但当只说动物时,我们是不知道是猫还是狗还是其他的.所以动物就是所谓的抽象类,猫和狗则是具体的类了.因此在Java中,一个没有方法体的方法应该定义为抽象类,而类中有抽象方法,则必须为抽象类. 2.抽象类的特点: 抽象类与抽象方法必须用abs

  • java中 Set与Map排序输出到Writer详解及实例

     java中 Set与Map排序输出到Writer详解及实例 一般来说java.util.Set,java.util.Map输出的内容的顺序并不是按key的顺序排列的,但是java.util.TreeMap,java.util.TreeSet的实现却可以让Map/Set中元素内容以key的顺序排序,所以利用这个特性,可以将Map/Set转为TreeMap,TreeSet然后实现排序输出. 以下是实现的代码片段: /** * 对{@link Map}中元素以key排序后,每行以{key}={val

  • java 中基本算法之希尔排序的实例详解

    java 中基本算法之希尔排序的实例详解 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差

  • java 中枚举类enum的values()方法的详解

    java 中枚举类enum的values()方法的详解 前言: 关于枚举,相信使用的已经很普遍了,现在主要写的是枚举中的一个特殊方法,values(), 为什么说特殊呢,因为在Enum 的 API 文档中也找不到这个方法.接下来就看看具体的使用. 理论上此方法可以将枚举类转变为一个枚举类型的数组,因为枚举中没有下标,我们没有办法通过下标来快速找到需要的枚举类,这时候,转变为数组之后,我们就可以通过数组的下标,来找到我们需要的枚举类.接下来就展示代码了. 首先是我们自己的枚举类. public e

随机推荐