【问题标题】:Is a private static field guaranteed to be non null when accessed from a static method if initialized in the private constructor如果在私有构造函数中初始化,则从静态方法访问时是否保证私有静态字段不为空
【发布时间】:2016-04-05 12:53:58
【问题描述】:

我有一个名为UrlController的类,方法是这样的:

public class UrlController {
    private static final String BASE_URL = "http://api.site.mil/";       

    private static Retrofit retrofit;

    private UrlController() {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    public static Retrofit getRetrofit() {
        return retrofit;
    }
} 

我应该在getRetrofit() 方法中检查if(retrofit==null) 还是它总是不为空?

【问题讨论】:

  • 为什么需要检查?它可以为空,也可以是另一个值。
  • 你是在做工厂方法吗?
  • 你应该对使用返回语句的目标类型进行检查。
  • 我想检查retrofit是否为空,实例化另一个Retrofit并返回
  • 为什么要在构造函数中创建静态链接实例而不是静态初始化块?

标签: java static initialization


【解决方案1】:

没有什么可以构造UrlController(除了UrlController,因为你的构造函数是private)所以retrofit保证是null。我想你想要一个 static 初始化器。类似的,

static {
    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

【讨论】:

  • 我能否从getRetrofit() 返回Retrofit 实例并确保实例不会为空?
  • static 初始化块将在 UrlController 加载时运行;如果您的 Builder 返回null,则实例将为null。将retrofit 引用标记为final 也是一个好主意。
  • 你们摇滚!不知道为什么我没有抓住这个想法。
  • 这段代码相当于只写public static final Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()).build()
【解决方案2】:

由于方法getRetrofitstatic,因此即使类的对象尚未创建,也可以调用它。

因此,您必须检查它。

但是即使你不检查,该方法也会返回null。因此,您必须在调用此方法的位置检查 null。

【讨论】:

    【解决方案3】:

    你想创建一个单例吗?

    因为现在你有一个只能在类中调用的私有构造函数。因此,您的改造字段将始终为空。此外,您可能想要使用这样的东西:

    public final class UrlController {
    private static final String BASE_URL = "http://api.site.mil/";     
    private static volatile Retrofit instance;
    
    private UrlController() {
        instance = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    
     public static Retrofit getInstance() {
            if (instance == null) {
                synchronized (UrlController.class) {
                    if (instance == null) {
                        instance = new UrlController();
                    }
                }
            }
            return instance;
        }
    
    } 
    

    这样你就可以简单地调用UrlController.getInstance(),你永远不会得到一个空值。

    【讨论】:

      猜你喜欢
      • 2016-11-29
      • 2016-08-17
      • 2015-06-28
      • 1970-01-01
      • 2010-11-14
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多