Java成员变量、局部变量的默认值和初始化

转载:https://blog.csdn.net/qq_24644517/article/details/82288493

package deep;

public class DefaultValue {
    // 实例成员变量
    private boolean bool;
    private byte b;
    private short s;
    private char c;
    private int i;
    private long l;
    private float f;
    private double d;
    private String str;
    private String[] strArray;
    // 静态成员变量
    private static boolean boolStatic;
    private static byte bStatic;
    private static short sStatic;
    private static char cStatic;
    private static int iStatic;
    private static long lStatic;
    private static float fStatic;
    private static double dStatic;
    private static String strStatic;
    private static String[] strArrayStatic;

    public void printInstanceField() {
        System.out.println("实例成员变量默认值:");
        System.out.println("boolean:" + bool);
        System.out.println("byte:" + b);
        System.out.println("short:" + s);
        System.out.println("char:" + c);
        System.out.println("int:" + i);
        System.out.println("long:" + l);
        System.out.println("float:" + f);
        System.out.println("double:" + d);
        System.out.println("String:" + str);
        System.out.println("String[]:" + strArray);
    }

    public static void printStaticField() {
        System.out.println("静态成员变量默认值:");
        System.out.println("boolean:" + boolStatic);
        System.out.println("byte:" + bStatic);
        System.out.println("short:" + sStatic);
        System.out.println("char:" + cStatic);
        System.out.println("int:" + iStatic);
        System.out.println("long:" + lStatic);
        System.out.println("float:" + fStatic);
        System.out.println("double:" + dStatic);
        System.out.println("String:" + strStatic);
        System.out.println("String[]:" + strArrayStatic);
    }

    public static void main(String[] args) {
        DefaultValue dv = new DefaultValue();
        dv.printInstanceField();
        dv.printStaticField();
    }
}

运行结果: 
实例成员变量默认值: 
boolean:false 
byte:0 
short:0 
char: 
int:0 
long:0 
float:0.0 
double:0.0 
String:null 
String[]:null 
静态成员变量默认值: 
boolean:false 
byte:0 
short:0 
char: 
int:0 
long:0 
float:0.0 
double:0.0 
String:null 
String[]:null

在本程序中声明了各种类型,分别为8种基本数据类型、引用类型、数组类型。并且声明为两组,一组为实例变量,一组为静态变量。然后一次输出两组数据的值。 
数组类型与引用类型的默认值相同,都为null,实际上,数组就是一种特殊的类(对象),所以数组类型的变量也就是引用类型的变量。从结果可知,相同类型的实例变量与静态变量默认值是相同的。 
这里有一点奇怪,char类型变量后面什么也没有输出。不过,这并不是char类型变量没有默认值,而是默认值为“空字符”,也就是‘\u0000’,数值为0,我们可以证明一下。 
例:

package deep;

public class CharDefaultValue {
    static char c;

    public static void main(String[] args) {
        System.out.println((int) c);
        System.out.println(c == '\u0000');
    }
}

运行结果: 

true

相对于成员变量,局部变量没有默认值(不管是什么类型),如果试图使用一个局部变量的值,而这个局部变量尚未初始化,就会产生编译错误,例如:

    public static void main(String[] args) {
        int value;
        System.out.println(value);
    }


错误提示: 
The local variable value may not have been initialized

但是,对于数组而言,如果数组使用new在堆上分配了空间,则数组的元素就会获得默认值,即使数组变量为局部变量也是如此。 
例:

    public static void main(String[] args) {
        int[] value = new int[10];
        System.out.println(value[0]);
    }


将会输出value[0]的默认值“0”。可以把数组的元素看作是数组的成员变量(实际上不是),当数组分配空间时,数组的元素(行为类似于成员变量)就可以获得默认的初始值。不过,对于局部变量数组本身(即value),如果没有初始化,同样没有默认值。
 

 

第二部分:Java变量的默认值和初始化

转载:https://www.cnblogs.com/slyfox/p/9703910.html

变量的默认值

注意只有成员变量才有默认值,而局部变量必须要赋初值。为什么会这么设计,下面会讨论。

关于各种基础类型的默认值,大家肯定都耳熟能详了,这里就不在叨叨,详见下表:
| 类型 | 值 |
|----------------------|-----------------------------------|
| Int | 0 |
| Long | 0 |
| Boolean | false |
| float | 0.0 |
| double | 0.0 |
| char | /u0000(NULL) |
| String | NULl |
| Object(代表所有的类) | NULL |
| 数组(未初始化) | NULL |
| 数组(已初始化) | 数组各个元素的值为,其类型的默认值 |

关于上表可以使用一下程序检测

public class Measurement {
    int i;
    long l;
    boolean b;
    float f;
    double d;
    char c;
    String s;
    Object o;
    int[] ints;

    public void printAll() {
        System.out.println("Java各数据类型的初始值如下\n" +
                "Int:" + i + "\n" +
                "Long:" + l + "\n" +
                "Boolean:" + b + "\n" +
                "Float:" + f + "\n" +
                "Double:" + d + "\n" +
                "Char:" + c + "\n" +
                "String:" + s + "\n" +
                "Object:" + o + "\n" +
                "Array:" + ints + "\n"
        );
    }
}

为什么有默认值

这个问题很好回答, 因为有些成员变量在初始的时候不知道赋什么初始的值 ? . 所以为了解决这个问题,Java干脆就直接给没有显式初始化的成员变量赋一个初始值。

初始值赋值的流程

成员变量赋默认值的过程是依照从上到下的循序来的。这一点,我们可以通过IDE来进行一下证明。

下面的程序是没有问题的,可以正常编译和运行

public class Circle {
    double r;
    double area = 3.14 * r * r;
}

再尝试下面的代码.

public class Circle {
    double area = 3.14 * r * r;
    double r;
}

上面的代码,根本就无法通过编译,编译器提示出现了 向前引用 的错误。从这个细节我们就可以推断出,默认值的的赋值过程是从上到下的。

局部变量必须显示初始化

上面我们提到了成员变量的默认值,那为什么在方法中的局部变量必须要显示地初始化呢?我想大家都写过类型下面这样的代码(直直接对一个没有初始化的变量进行操作)。

public void test() {
    int i;
    i++;
}

显然,编译器 在这里显得有点“事多儿”,可以转念一想确实应该这样做,在上面的代码中如果 i 直接就有一个默认值的话,那么上面就不会保存,但是我们的业务可能并不是想要 i 变量的初始值是 0 , 因为出现这种情况的时候,绝大部分是忘记了给变量初值,而不是想要使用变量的默认值,所以编译器就事先就替我们解决了这个问题--所有的局部变量必须要有初值 通过这种强制的手段来避免了很多无谓的错误。

那么为什么成员变量,又有默认值了呢?那是因为,如果必须要为一个成员变量显示地赋初值,那这真是一个令人伤脑筋的事情,在编程的时候,一般来说,成员变量的初始值并不会被在声明的时候就赋值,因为有很多的成员变量需要经过一系列的计算才能得到其值(并不能直接赋予)。所以编译器在这又显得有点“碌碌无为”。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值