在类中使用静态“对象”的空指针异常

时间:2014-06-06 01:35:49

标签: java android static

我尝试使用Google的实用程序功能来命名图像文件。

我从相机应用程序的Util.java中取出它们。 许可证:

/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

我为他们编写单元测试并且遇到了createJpegName

的问题
public class Util {
    private static ImageFileNamer sImageFileNamer;
    // don't instantiate this class, dummy
    private Util() {
    }
    public static String createJpegName(long dateTaken) {
    synchronized (sImageFileNamer) {
        return sImageFileNamer.generateName(dateTaken);
    }
    }
    private static class ImageFileNamer {
    private SimpleDateFormat mFormat;
    // The date (in milliseconds) used to generate the last name.
    private long mLastDate;
    // Number of names generated for the same second.
    private int mSameSecondCount;

    @SuppressWarnings("unused")
    public ImageFileNamer(String format) {
        mFormat = new SimpleDateFormat(format, Locale.US);
    }

    public String generateName(long dateTaken) {
        Date date = new Date(dateTaken);
        String result = mFormat.format(date);
        // If the last name was generated for the same second,
        // we append _1, _2, etc to the name.
        if (dateTaken / 1000 == mLastDate / 1000) {
        mSameSecondCount++;
        result += "_" + mSameSecondCount;
        } else {
        mLastDate = dateTaken;
        mSameSecondCount = 0;
        }
        return result;
    }
    }

单元测试,为子孙后代:

public void testCreateJpegName() {
// public static String createJpegName(long dateTaken)
Calendar dateTime = Calendar.getInstance();
dateTime.set(1976, Calendar.SEPTEMBER, 20, 16, 20, 20);
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020");
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020_1");
}

所以..我假设sImageFileNamer没有被实例化,因为我从不创建一个Util对象,对吗?

这是如何使用的?我错过了什么吗?

我可以就地使用的其余util函数。

每当我尝试访问sImageFileNamer时,我都会得到一个NPE,在上面它发生在同步()的调用中。

谢谢!

2 个答案:

答案 0 :(得分:1)

在使用sImageFileNamer块之前,您没有初始化synchronized实例,请执行以下操作:

 public static String createJpegName(long dateTaken) {
        sImageFileNamer=  new ImageFileNamer(dateTaken);
        synchronized (sImageFileNamer) {
            return sImageFileNamer.generateName(dateTaken);
         }
    }

或类和generateName方法都是static,因此您无需使用类名创建对象即可访问。

答案 1 :(得分:0)

您必须确保在使用之前初始化sImageFileNamer。因为它是私有的,所以你只能从Util类中进行。我建议你从某种方法做到这一点或使用静态初始化器:

public class Util {
    private static ImageFileNamer sImageFileNamer;
    static {
        sImageFileNamer = null; // replace null by whatever you want
    }
    // ... continue you class code
}

如上所述here,静态初始值设定项只会自动调用一次。我认为这就是你所需要的。