转载-定义时初始化和构造器初始化的差异

Posted silence-fire

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转载-定义时初始化和构造器初始化的差异相关的知识,希望对你有一定的参考价值。

 
  1. 概述
    1. 在Java中使用一个变量时,如果我们不给变量初始化,则编译器会自动给变量初始化赋值,使得所有的变量在使用前都能得到恰当的初始化。
    2. 对于方法中的局部变量,如果不初始化就使用,则会报错(类似“The local variable i may not have been initialized”的错误信息)。
  2. 举例
    1. Dog类代码如下:
      技术分享图片
      public class Dog implements Serializable {
      
      private static final long serialVersionUID = 2239821175446189806L;
      private String kind;
      private String name = "jack";
      private int i;
      private double d;
      private float f;
      private byte b;
      private short s;
      private long l;
      private char c;
      private boolean bl;
      private Order order;
      
      public Dog() {
      System.out.println(this.name);
      System.out.println(this.kind);
      this.kind = "哈士奇";
      System.out.println(this.kind);
      System.out.println("编译器为int类型设置的初始化默认值为:" + i);
      System.out.println("编译器为double类型设置的初始化默认值为:" + d);
      System.out.println("编译器为float类型设置的初始化默认值为:" + f);
      System.out.println("编译器为byte类型设置的初始化默认值为:" + b);
      System.out.println("编译器为short类型设置的初始化默认值为:" + s);
      System.out.println("编译器为long类型设置的初始化默认值为:" + l);
      System.out.println("编译器为char类型设置的初始化默认值为:" + c);
      System.out.println("编译器为boolean类型设置的初始化默认值为:" + bl);
      System.out.println("编译器为引用类型(如Order)设置的初始化默认值为:" + order);
      }
      
      public Dog(String name) {
      this.name = name;
      }
      
      public String getKind() {
      return kind;
      }
      
      public void setKind(String kind) {
      this.kind = kind;
      }
      
      public String getName() {
      return name;
      }
      
      public void setName(String name) {
      this.name = name;
      }
      
      public Order getOrder() {
      return order;
      }
      
      public void setOrder(Order order) {
      this.order = order;
      }
      
      }
      View Code
    2. Order代码如下:
      技术分享图片
      public class Order implements Serializable {
       2 
       3     private static final long serialVersionUID = 7441323999887439757L;
       4 
       5     private String orderNo;
       6     private String orderType;
       7 
       8     public Order( String str) {
       9         System.out.println(str);
      10     }
      11 
      12     public String getOrderNo() {
      13         return orderNo;
      14     }
      15 
      16     public void setOrderNo(String orderNo) {
      17         this.orderNo = orderNo;
      18     }
      19 
      20     public String getOrderType() {
      21         return orderType;
      22     }
      23 
      24     public void setOrderType(String orderType) {
      25         this.orderType = orderType;
      26     }
      27 }
      View Code
      技术分享图片
       1 public class Order implements Serializable {
       2 
       3     private static final long serialVersionUID = 7441323999887439757L;
       4 
       5     private String orderNo;
       6     private String orderType;
       7 
       8     public Order( String str) {
       9         System.out.println(str);
      10     }
      11 
      12     public String getOrderNo() {
      13         return orderNo;
      14     }
      15 
      16     public void setOrderNo(String orderNo) {
      17         this.orderNo = orderNo;
      18     }
      19 
      20     public String getOrderType() {
      21         return orderType;
      22     }
      23 
      24     public void setOrderType(String orderType) {
      25         this.orderType = orderType;
      26     }
      27 }
      技术分享图片
    3. 执行类代码如下:
      技术分享图片
      public class Test {
      2     public static void main(String[] args) {
      3         Dog d = new Dog();
      4     }
      5 }
      View Code
      1 public class Test {
      2     public static void main(String[] args) {
      3         Dog d = new Dog();
      4     }
      5 }
    4. 执行结果如下图:
      1. 技术分享图片
    5. 分析如下:
      1. 由Dog类代码可知,成员变量kind是在构造方法中初始化的,成员变量name是在定义时初始化的,其他变量则没有初始化。
      2. 在main方法中创建了Dog对象,将调用构造方法。
      3. 构造方法中第一行代码是打印成员变量name的值,由于name在定义时就初始化了,所以name的值就是其定义时初始化的值“jack”;
      4. 构造方法中第二行代码是打印成员变量kind的值,虽然kind没有在定义时初始化,但是上图显示的结果却是null,这说明编译器为kind初始化了一个null值。
      5. 构造方法中第三行代码则是为kink赋值为“哈士奇”,所以第四行代码自然而然的打印出了kind的值是“哈士奇”。
      6. 构造方法的第五行代码之后,都是打印的未初始化的变量的值,由上面截图可知,虽然没有给这些变量赋值,但是他们却都打印出了值。
    6. 结论:
      1. 如果我们没有给变量赋值,则编译器会自动为每个变量赋一个恰当的值,具体情况如下:
        1. int类型的初始化默认值是 0   
        2. double类型的初始化默认值是 0.0d
        3. float类型的初始化默认值是 0.0f
        4. byte类型的初始化默认值是 0
        5. short类型的初始化默认值是 0
        6. lang类型的初始化默认值是 0
        7. char类型的初始化默认值是 “\\0000”
        8. boolean类型的初始化默认值是 false
        9. 引用类型(如Order)的初始化默认值是 null
        10. 另外,数组引用类型的变量的默认值为 null。当数组变量实例化后,如果没有没有显示的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。
      2. 定义时初始化和构造器初始化的差异:变量定义时初始化的次数是一次,如上面的变量name;而构造器初始化的次数是两次,首先编译器发现kind没有初始化,自动为kind赋null值,然后在构造方法中,再次初始化为“哈士奇”。

注:此文章为转载内容,原网址见:http://www.cnblogs.com/yanglz528/p/7821837.html




以上是关于转载-定义时初始化和构造器初始化的差异的主要内容,如果未能解决你的问题,请参考以下文章

Golang创建构造函数的方法详解

Java和CSharp的类继承的执行过程的差异

(转载)虚幻引擎3--UnrealScript教程章节一:16.DefaultProperties

构造代码块局部代码块和静态代码块的定义作用和区别

类和对象的加载先后

将初始数据提供给片段的正确方法?