Java中初始化块的真实作用

本文探讨了Java中初始化块的使用场景及其优势,并通过示例对比了在不同构造函数中重复初始化代码与使用初始化块的区别。特别强调了在匿名内部类中初始化块的重要性。

          声明:本博客为原创博客,未经允许,不得转载!原文链接为 http://blog.csdn.net/bettarwang/article/details/27128323

      对于普通的类而言,可以放在初始化块中的初始化工作其实完全可以放到构造函数中进行,只不过有时会带来些许不便,如有多个构造器,就要在多个地方加上初始化函数完成初始化工作,而如果放到初始化块中的话则只要写一次即可。如下例所示:

import java.util.*;

public class Car
{
   private void init()
   {
      System.out.println("Start engine before run()");
   }
    
   public Car()
   {
      init();
      System.out.println("Run normally");
   }
   
   public Car(float velocity)
   {
      init();
      System.out.println("Run with "+velocity+" miles/h");
    }

   public static void main(String[]args)
   {
      new Car();
      new Car(210f);
   }
}
输出结果如下:


如果使用初始化块,则代码如下:

import java.util.*;

public class Car
{
   private void init()
   {
      System.out.println("Start engine before run()");
   }
    
   //使用初始化块
   {
     init();
    }
  

   public Car()
   {
      //init();
      System.out.println("Run normally");
   }
   
   public Car(float velocity)
   {
      //init();
      System.out.println("Run with "+velocity+" miles/h");
    }

   public static void main(String[]args)
   {
      new Car();
      new Car(210f);
   }
}

显然,使用初始化块的代码比不使用初始化块的代码要更简洁。
但是,如果只是这一点便利的话,还不足以使用初始化块,其实初始化块真正体现其独一无二的作用是在匿名内部类中,由于是匿名内部类,因而无法写构造方法,但是很多时候还是要完成相应的初始化工作,这时就需要用到初始化块了,特别是Android中大量地使用匿名内部类,初始化块的作用就十分突出,如下例所示:

import java.util.*;

interface Vehicle
{
  public void run();
  public void carry(); 
 }

class Person
{
  public void drive(Vehicle vehicle)
  {
    vehicle.run();
   }
}

public class AnonymousSample
{
   public static void main(String[]args)
   {
      Person person=new Person();
      person.drive(new Vehicle()
      {
        private void init()
        {
           System.out.println("Start engine befor run()");
        }
        
        //匿名类中只能使用普通初始化块来完成初始化工作
        {
          init(); 
         }

        @Override
        public void run()
        {
           System.out.println("Car can run with high velocity on freeway.");
        }
        @Override
        public void carry()
        {
           System.out.println("Car can carry 3 persons at least.");
         }
      });
   }
}
输出结果如下:


显然,在本例中,由于实现Vehicle的匿名内部类没有名字,自然也不能有显式的构造方法,从而无法在构造方法中完成初始化工作,但是如果不完成初始化就无法正常启动,所以此时就要借助初始化块。


<think> 首先,用户的问题是:“我想了解Java中List初始化包含的步骤 请问Java中List初始化的步骤有哪些”。用户提供了几个引用,但这些引用是关于数组初始化和Lambda表达式转换的。 用户要求参考站内引用,所以我需要查看这些引用: - 引用[1]:关于使用Java Lambda表达式将List转换为另一个List,强调Stream API和Lambda的使用。 - 引用[2]:关于Java对象初始化和类初始化的区别,new一个对象的详细过程等。 - 引用[3]:关于Java初始化数组的方法,讨论数组作为引用类型,初始化步骤。 - 引用[4]:关于Java数组静态初始化,数组定义和初始化方法。 用户的核心问题是关于List初始化的步骤。List不同于数组;List是集合接口,通常在Java中使用ArrayList、LinkedList等实现。 我的回答需要结构化,并参考这些引用。尽管引用主要讨论数组,但可能有相似之处,比如引用[3]中提到数组初始化分为两步:对数组对象初始化(分配内存和赋值)和对数组名初始化(赋值引用)。类似地,List初始化可能涉及创建对象和赋值。 用户提到“List初始化”,可能包括创建List对象和添加元素。 在Java中,List初始化的步骤通常包括: 1. 声明List变量。 2. 创建List对象(如使用new运算符)。 3. 添加元素(可选,但通常是初始化的一部分)。 4. 初始化元素(如使用构造函数或添加方法)。 Java支持静态初始化和动态初始化: - 静态初始化:使用双括号初始化或Arrays.asList。 - 动态初始化:创建对象后逐个添加元素。 根据系统指令: - 回答必须使用中文。 - 结构清晰,帮助用户逐步解决问题。 - 添加引用标识,自然地引用相关段落。 - 生成相关问题。 参考用户提供的引用: - 引用[1]提到List转换,但用户的问题是初始化,不是转换。 - 引用[2]关于对象初始化和类初始化,可能相关,因为List实例化涉及new对象。 - 引用[3]和[4]关于数组初始化,可以类比到List。 我应该在回答中引用相关部分。例如,引用[3]说:“数组初始化就是让数组名指向数组对象的过程,该过程主要分为两个步骤,一是对数组对象进行初始化,即为数组中的元素分配内存空间和赋值,二是对数组名进行初始化,即为数组名赋值为数组对象的引用。” 这类似List初始化。 同样,引用[2]讨论new对象的过程,包括类加载、实例初始化等。 所以,我可以将List初始化步骤概述为: 1. 声明List变量:指定类型。 2. 创建List对象:使用new关键字创建ArrayList或其他实现。 3. 初始化元素:添加元素或使用构造函数。 步骤: - 静态初始化:List<String> list = Arrays.asList("a", "b"); 或 List<Integer> list = new ArrayList<>(List.of(1,2,3)); - 动态初始化:List<String> list = new ArrayList<>(); list.add("Hello"); list.add("World"); 更深层次,涉及Java初始化机制: - 类加载:当第一次使用List类时,JVM加载类。 - 实例初始化:创建对象时,分配内存、初始化默认值、执行构造函数。 参考引用[2]。 回答结构: 1. 介绍List初始化。 2. 逐步解释步骤。 3. 引用相关部分。 4. 生成相关问题。 最后,添加引用标识。 生成相关问题: - 例如,"Java中List的不同实现类有什么区别?" 或 "如何优化List初始化性能?" 确保回答真实可靠。 </think> ### Java中List初始化的步骤 在Java中,List是集合框架的核心接口(如`java.util.List`),它需要通过具体实现类(如`ArrayList`或`LinkedList`)来初始化。List初始化主要包括声明变量、创建对象、添加元素等步骤,这与数组初始化类似,但List更加灵活(因为它是动态集合而非固定大小的数组)。初始化过程涉及Java的对象创建机制,包括类加载、实例初始化和内存分配等。下面我将逐步解释List初始化的详细步骤,基于Java的通用实践和相关引用内容。整个流程聚焦于"初始化"的核心:**让List变量指向有效的List对象,并为对象分配内存和赋值元素**。 #### List初始化的主要步骤 1. **声明List变量** 这是初始化的第一步,指定List的类型(如泛型类型)和变量名。此时变量只是一个引用,还未指向任何对象,类似于数组声明(如引用[3]所述)。 - 示例:`List<String> myList;` - 说明:声明了`myList`变量,类型为`List<String>`,但此时变量值为`null`,未分配内存。这类似于数组声明中的`int[] arr;`(引用[3]:"声明数组只是声明一个引用类型的变量")。 2. **创建List对象(分配内存)** 使用`new`关键字创建List的对象实例(如`ArrayList`或`LinkedList`)。这一步触发JVM的内存分配和对象初始化过程。 - 示例(动态初始化):`myList = new ArrayList<>();` - 详细过程: - **类加载**:如果List实现类(如`ArrayList`)首次使用,JVM加载该类(通过类加载器),执行静态初始化(如静态变量赋值)。这类似于引用[2]中提到的"类加载过程"。 - **对象创建**:`new`运算符分配堆内存,初始化对象默认值(如字段为`null`或0),并调用构造函数(如`ArrayList()`构造函数初始化内部数组)。这对应引用[2]的"new一个对象的详细过程",包括内存分配和实例初始化执行。 - **结果**:变量`myList`现在指向一个有效的List对象,但列表内容为空(容量可能默认初始化,如`ArrayList`的默认容量为10)。 3. **添加和初始化元素(赋值元素)** 这一步是可选的,但通常是初始化的关键部分。元素可以通过多种方式添加:在创建对象时静态初始化,或在创建后动态添加。 - **静态初始化(一次性赋值)**: 使用工具类(如`Arrays.asList`)或Java 9+的`List.of`方法,在声明时直接赋值元素。 - 示例:`List<String> myList = Arrays.asList("A", "B", "C");` - 说明:元素在对象创建时被分配内存空间并赋值,这类似于数组的静态初始化(引用[4]:"数组静态初始化")。 - **动态初始化(逐步添加)**: 创建对象后,使用`add()`方法添加元素。 - 示例:`myList.add("Hello"); myList.add("World");` - 说明:元素逐步添加到List内部结构中(如`ArrayList`的动态扩容数组),这与引用[3]描述的数组初始化第二步"为数组中的元素分配内存空间和赋值"类似。 - **使用构造函数初始化**: 可以通过构造函数传递集合或数组来实现初始化。 - 示例:`List<Integer> numList = new ArrayList<>(List.of(1, 2, 3));` - 说明:这结合了对象创建和元素赋值,一步完成。 4. **完整初始化示例** 综合上述步骤,一个典型的List初始化代码如下: ```java // 步骤1: 声明变量 List<String> fruits; // 步骤2: 创建对象 (触发内存分配) fruits = new ArrayList<>(); // 步骤3: 添加元素 (赋值) fruits.add("Apple"); fruits.add("Banana"); ``` 或使用简洁的静态初始化: ```java List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana")); // 声明、创建对象和赋值一步完成 ``` #### 关键注意事项 - **内存管理和性能**:List初始化涉及堆内存分配。动态添加元素时(如`ArrayList`),如果超出初始容量,JVM会自动扩容(创建新数组并复制元素),这可能影响性能。为提高效率,可以在创建对象时指定初始容量:`List<String> list = new ArrayList<>(20);`(引用[3]的"为数组中的元素分配内存空间"原理类似)。 - **与数组初始化的区别**:数组是固定大小,而List是动态的。数组初始化如引用[3]所述分两步(对象初始化和变量赋值),List也类似,但List的元素类型更灵活(支持泛型),且添加元素时不需预设大小。 - **初始化时机**:List初始化通常在方法内部或构造函数中执行。如果作为类字段,实例初始化(如`{ ... }`)或构造函数用于确保正确初始化(引用[2]:"实例初始化在创建对象时执行")。 - **Java初始化的深层机制**:List初始化依赖于JVM的类加载和对象生命周期(引用[2])。创建List对象时: - JVM加载`ArrayList`类(如果未加载)。 - 分配内存,执行构造函数初始化内部状态。 - 变量赋值后,List对象才可用。 通过上述步骤,Java中的List初始化确保了变量指向有效的集合对象,并可灵活处理元素。这提高了代码可读性和简洁性(引用[1]),尤其在处理集合数据转换时(如使用Lambda表达式)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值