【问题标题】:Calling non-static method from static member in Java从Java中的静态成员调用非静态方法
【发布时间】:2014-07-28 12:31:02
【问题描述】:

这个问题比较复杂,不知道以前有没有被问过,因为我不知道如何在搜索框中表达这个问题。

代码如下:

public class SomeClass 
{
  private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

  public static String toUTCDateString(Date date)
  {
    df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
    return df.format(date);
  }

  /* more static methods */
}

静态成员df 将在更多静态方法中再次使用,但我需要先将其时区设置为“UTC”。有没有办法一劳永逸地拨打.setTimeZone("UTC")?还是我必须在每个静态方法中调用.setTimeZone("UTC")

【问题讨论】:

  • 请注意SimpleDateFormat 不是线程安全的。如果多个线程同时使用同一个静态SimpleDateFormat 对象,将会得到意想不到的结果。
  • 感谢您的提示。正式注明!

标签: java


【解决方案1】:

使用Static Initialization Blocks

静态初始化块是用大括号 { } 括起来并以 static 关键字开头的普通代码块。这是一个例子:

static {
    // whatever code is needed for initialization goes here
}

一个类可以有任意数量的静态初始化块,它们可以出现在类主体的任何地方。运行时系统保证静态初始化块按照它们在源代码中出现的顺序被调用。

示例代码:

public class SomeClass 
{
      private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

      //Static Initialization Blocks
      static{
           df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
      }

      public static String toUTCDateString(Date date)
      {     
          return df.format(date);
      }

     /* more static methods */
}

【讨论】:

  • 哇,就这么简单?我从来不知道java中的静态初始化块。 >_
  • 是的,我阅读了链接。或者,我也可以使用私有静态初始化方法来初始化我的静态成员。谢谢! 5分钟后我会接受答案!
  • 通过使用上面的代码,您必须同步对 SimpleDateFormat 的访问,因为它不是线程安全的,如果同时调用可能会导致意外结果
  • 作为替代方案,使用Joda-Time 库确保线程安全。
  • OP 根本不是在谈论线程安全。可能是 OP 没有在多线程环境中使用代码。
【解决方案2】:

不幸的是! SimpleDateFormat 不是安全的:它保持内部状态,同时使用会造成严重破坏。

这“解决”了您的问题,因为您必须更改 API。

public static DateFormat df()
{
    DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
    return df;
}

在 Java 8 中使用其他更好的类解决了这个问题。

顺便说一句,yyyy-MM-dd 是 ISO 标准。

【讨论】:

    猜你喜欢
    • 2016-01-13
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多