HardBirch

Java变量初始化问题探究

时间:13-07-17 栏目:JAVA语言-JVM虚拟机 作者:张飞不张,文采横飞 评论:0 点击: 2,096 次

对于java的变量,我们知道有成员变量和局部变量。

关于他们的初始化,基本上所有书上都会写。成员变量,java会帮助你初始化,局部变量,则需要程序员自己初始化。

对于类的成员变量。不管程序有没有显示的初始化,Java  虚拟机都会先自动给它初始化为默认值。

规则为:

1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。

2、单精度浮点型(float)的基本类型变量的默认值为0.0f。

3、双精度浮点型(double)的基本类型变量的默认值为0.0d。

4、字符型(char)的基本类型变量的默认为 “/u0000”。

5、布尔性的基本类型变量的默认值为 false。

6、引用类型的变量是默认值为 null。

7、数组引用类型的变量的默认值为 null。春关键数组变量的实例后,如果没有没有显示的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。

局部变量初始化

 

局部变量声明以后,Java 虚拟机不会自动的为它初始化为默认值。因此对于局部变量,必须先经过显示的初始化,才能使用它。

如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。

 

那么,加了修饰的java成员变量是如何初始化的呢?在何时?在程序中的什么位置?

下面看个小程序。

 

  1. public class TestC {
  2.     /*
  3.      * 定义成员变量
  4.      * 尾数为1表示定义时进行初始化赋值
  5.      * 尾数为2表示在代码块中进行初始化赋值
  6.      * 尾数为3表示在构造函数中进行初始化赋值
  7.      * 尾数为4表示在静态代码块中进行初始化赋值
  8.      * 尾数为5表示不初始化赋值
  9.      */
  10.     /*
  11.      * 普通成员变量
  12.      */
  13.     int field_a1 = 5;
  14.     int field_a2;
  15.     int field_a3;
  16.     //报错:不能再静态代码块中使用非静态变量。 Cannot make a static reference to the non-static field field_a4
  17.     //int field_a4;
  18.     int field_a5;
  19.     /*
  20.      * final 成员变量
  21.      */
  22.     final int  field_b1 = 5;
  23.     final int  field_b2;
  24.     final int  field_b3;
  25.     //报错:不能再静态代码块中使用非静态变量。Cannot make a static reference to the non-static field field_b4
  26.     //final int  field_b4;
  27.     //报错:未初始化 。The blank final field field_b5 may not have been initialized
  28.     //final int  field_b5;
  29.     /*
  30.      * static成员变量
  31.      */
  32.     static int field_c1 = 5;
  33.     static int field_c2;
  34.     static int field_c3;
  35.     static int field_c4;
  36.     static int field_c5;
  37.     /*
  38.      * static final 成员变量
  39.      */
  40.     static final int field_d1 = 5;
  41.     //报错:未初始化 。The blank final field field_d2 may not have been initialized
  42.     //static final int field_d2;
  43.     //报错:未初始化 。The blank final field field_d3 may not have been initialized
  44.     //static final int field_d3;
  45.     static final int field_d4;
  46.     //报错:未初始化 。The blank final field field_d5 may not have been initialized
  47.     //static final int field_d5;
  48.     //代码块
  49.     {
  50.         field_a2 = 5;
  51.         field_b2 = 5;
  52.         field_c2 = 5;
  53.         //field_d2 = 5;
  54.     }
  55.     //静态代码块
  56.     static{
  57.         //field_a4 = 5;
  58.         //field_b4 = 5;
  59.         field_c4 = 5;
  60.         field_d4 = 5;
  61.     }
  62.     //构造函数
  63.     public TestC(){
  64.         field_a3 = 5;
  65.         field_b3 = 5;
  66.         field_c3 = 5;
  67.         //field_d3 = 5;
  68.     }
  69. }

然后我们对这个程序生成的.class文件进行反编译,看看他是如何运行的。

下面是TestC.jad文件。反编译文件

  1. public class TestC
  2. {
  3.     public TestC()
  4.     {
  5.         field_a1 = 5;
  6.         field_a2 = 5;
  7.         field_c2 = 5;
  8.         field_a3 = 5;
  9.         field_c3 = 5;
  10.     }
  11.     int field_a1;
  12.     int field_a2;
  13.     int field_a3;
  14.     int field_a5;
  15.     final int field_b1 = 5;
  16.     final int field_b2 = 5;
  17.     final int field_b3 = 5;
  18.     static int field_c1 = 5;
  19.     static int field_c2;
  20.     static int field_c3;
  21.     static int field_c4 = 5;
  22.     static int field_c5;
  23.     static final int field_d1 = 5;
  24.     static final int field_d4 = 5;
  25. }

看到这里我们就很有清晰的思路了。

对于不加修饰的普通成员变量,无论我们在什么地方对其进行初始化赋值,系统都会默认在构造函数中进行赋值。

对于final变量,无论我们在什么地方进行赋值,系统会默认final变量是在类中进行初始化。

 

通过报错,我们可以发现。

final变量必须进行初始化。否则就会报编译错误The blank final field field_d5 may not have been initialized

static成员变量的初始化发生在类被类加载器(classLoader)加载的时候系统会对没有初始化的静态成员变量在静态区进行默认赋值

普通成员变量的初始化发生在JVM为类生成实例开辟空间的时候进行默认初始化赋值。

声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: Java变量初始化问题探究

Java变量初始化问题探究:等您坐沙发呢!

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐