成员初始化

成员初始化

局部变量须初始化,否则编译错误。

类的字段若为基本类型,则会自动初始化,char为空,对象引用为null,boolean为false,其余为0。

指定初始化

C++中所不允许,可直接在类的定义的时候给出初值,并可以通过函数等各种方式进行赋值。

public class InitialValues2 {
    boolean bool = true;
    char ch = 'x';
    byte b = 47;
    double d = 3.14159;
    int i = f();
  	int j = g(i);
  	int f() { return 11; }
  	int g(int n) { return n * 10; }
} 

构造器初始化

  • 自动初始化在构造器初始化前发生,当然也发生在指定初始化前。
初始化顺序
  • 在类的内部,定义变量的先后顺序决定了自动初始化的顺序,且均在构造器初始化前初始化。
静态数据的初始化
  • 初始化的顺序为:先静态对象,再非静态对象。
  • 对象创建过程:
    • 构造器实际上也是静态方法,所以类型为 Dog 的一个对象首次创建时,或者 Dog 类的 static 方法/ static 字段首次访问时,Java 解释器必须找到 Dog.class
    • 找到 Dog.class 后(它会创建一个 Class 对象,这将在后面学到),它的所有 static 初始化模块都会运行。因此, static 初始化仅发生一次—— 在 Class 对象首次载入的时候。
    • 创建一个 new Dog()时, Dog 对象的构建进程首先会在内存堆( Heap)里为一个 Dog 对象分配足够多的存储空间。
    • 这种存储空间会清为零,将 Dog 中的所有基本类型设为它们的默认值(零用于数字,以及 boolean 和
      char 的等价设定)。
    • 进行字段定义时发生的所有初始化都会执行。
    • 执行构建器。
显示静态初始化
  • 静态初始化块,与静态初始化动作相同。给静态成员进行初始化,只初始化一次

    public class Spoon {
        static int i;
        static {
            i = 47;
        }
    } 
    
  • 实例初始化,无static关键字,这对于支持匿名内部类是必须的,且在构造器前被调用。每次创建新的对象是都会调用。

    import static net.mindview.util.Print.*;
    
    class Mug {
        Mug(int marker) {
            print("Mug(" + marker + ")");
        }
        void f(int marker) {
            print("f(" + marker + ")");
        }
    }
    
    public class Mugs {
        Mug mug1;
        Mug mug2;
        {
            mug1 = new Mug(1);		//每次都会调用
            mug2 = new Mug(2);
            print("mug1 & mug2 initialized");
        }
        Mugs() {
            print("Mugs()");
        }
        Mugs(int i) {
            print("Mugs(int)");
        }
        public static void main(String[] args) {
            print("Inside main()");
            new Mugs();
            print("new Mugs() completed");
            new Mugs(1);
            print("new Mugs(1) completed");
        }
    } /* Output:
    Inside main()
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs()
    new Mugs() completed
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs(int)
    new Mugs(1) completed
    *///:~
    
初始化的可能位置
  1. 定义对象的地方
  2. 类的构造器中
  3. 就在正要使用这些对象前。这被称为惰性初始化。在生成对象不值得及不必每次都生成对象的情况下,这样可以减少负担。
    • 如在toString()中进行初始化
  4. 使用实例初始化(静态/非静态)

数组初始化

  • 数组的 = 赋值并不分配新的空间,而是一种别名

  • 数组的创建时不需要明确有多少个元素,可运行时给出。数组初始化时若是基本类型会给出对应的空值,若是对象数组,则仅仅创建了引用数组,需要一次创建新的对象。

    public static void main(String[] args) {
        //Method1
        Integer[] a = {
            new Integer(1),
            new Integer(2),
            3, // Autoboxing
    	};
        //Method2
        Random rand = new Random(47);
        Integer[] a = new Integer[rand.nextInt(20)];
        for(int i = 0; i < a.length; i++)
            a[i] = rand.nextInt(500); // Autoboxing
    }
    
  • 可变参数列表

    • 获得的仍然是一个数组,可用foreach迭代。当然,如果传进去的就是数组,则不用进行转化

    • 可变参数处可以不传入实参。这个特性可以用于作为可选的尾随参数

      public class OptionalTrailingArguments {
          static void f(int required, String... trailing) {
              System.out.print("required: " + required + " ");
              for(String s : trailing)
                  System.out.print(s + " ");
              System.out.println();
          }
          public static void main(String[] args) {
              f(1, "one");
              f(2, "two", "three");
              f(0);
          }
      }/* Output:
      required: 1 one
      required: 2 two three
      required: 0
      *///:~
      
    • 当可变参数列表中的类(Integer)遇到基本数据类型(int)时,会自动进行参数提升

    • 对于可变参数的重载,f()会产生ambiguous问题,须对于每个含有可变参数的重载函数提供一个非可变参数。实际上,应尽量避免在多个重载函数中使用可变参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值