当我们已经有了静态方法时,为什么要使用静态块?

时间:2018-09-16 15:39:26

标签: java

为什么可以使用静态方法初始化静态变量时为什么使用静态块?有什么区别?这是什么逻辑?

3 个答案:

答案 0 :(得分:7)

我假设您指的是静态初始化程序块?

static { ... }

静态初始化程序块和静态方法都是必需的,因为它们执行不同的操作。

静态初始化程序块是用于初始化类的块。当类加载时,它们仅运行一次。它们不返回任何内容,也不能引发检查异常,因为没有办法声明throws

实际上是带有初始化程序的静态字段:

static int a = 0;

实际上已转换为字段声明和静态初始化程序块:

static int a;

static {
  a = 0;
}

您可以在静态初始值设定项中分配零个或多个静态最终变量,前提是尚未分配这些变量。

静态方法可以随时调用。他们可以返回一个值,并抛出检查异常。您不能使用静态方法分配静态最终变量(尽管您可以分配非最终静态变量)。

答案 1 :(得分:1)

您正在考虑有关初始化对象的两种不同想法。例如:

class A {
   static Map<String, String> map;

   static {
      map = new HashMap<String, String>();
   }

   public static void initializeMap() {
       map = new HashMap<String, String>();
   }

   public static void insert(String key, String value) {
       map.put(key, value);
   }
}

如果我们使用静态初始化程序块,则第一次使用任何静态方法(即insert),它将首先运行静态块。这样,您就可以安全地进行并发控制。即:一开始就有多个线程尝试调用方法insert,Java只会运行一次initialize块。

在这种情况下,使用静态方法进行初始化,例如initializeMap,优点是您可以将运行init的控件移到自己的程序中。也许您的班级不应该尽快初始化,而只有程序告诉您这样做。另一个优点是您可以控制返回值,或者在需要时引发异常(您不能在静态初始化程序块中引发异常)。

请注意,上述静态方法并不安全,因此不应同时调用。换句话说,您应该确保只有一个线程调用该方法来初始化映射。否则,必须添加锁以控制多线程访问。

关于使用静态初始化程序块的优点的其他说明:

  • 处理Java自动提供的并发访问。
  • 某些程序我们不确切知道将静态方法放在哪里,因此使用静态初始化程序是一个安全的选择。
  • 某些复杂的初始化不能在一行中完成,因此静态初始化是唯一的选择。

答案 2 :(得分:0)

您可以使用静态块来执行更复杂的初始化,例如,您只想确保目录存在的上载队列。

static {
    File f = new File(getUploadDir());
    if(!f.exists()) {
        //noinspection ResultOfMethodCallIgnored
        f.mkdir();
    }
}

您也可以使用它在静态对象上设置一些属性。这是一个示例:

private static final SimpleDateFormat mDateTimeFormat = new 
      SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);

static {
    mDateTimeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}