【问题标题】:Why can I not instantiate LocationManager class? [closed]为什么我不能实例化 LocationManager 类? [关闭]
【发布时间】:2014-04-25 05:34:29
【问题描述】:

我正在尝试使用 LocationManager 类做一些工作,但发现我无法实例化它。

它不是一个抽象类,我的印象是只有标记为抽象的类不能被实例化。

【问题讨论】:

  • 可能构造函数是私有的,如果是私有的则不能在类外初始化
  • 构造函数是私有的。你必须从Context#getSystemService(Context.LOCATION_SERVICE);获取系统的LocationManager服务
  • 不能直接实例化它,但是你正在使用的其他东西可以并且可以(文档的第二段)。这是简单的访问控制,很常见。
  • 嗯,这是我想念的东西,但从未意识到。谢谢大家。
  • 跟上反对票的人,这里的每个人都应该是约翰卡马克。

标签: java android access-control


【解决方案1】:

更完整的答案:

如果您查看source code for LocationManager,特别是第 303 行,您会发现它实际上确实有一个公共构造函数......但是有一个特殊的注释:

/**
 * @hide - hide this constructor because it has a parameter
 * of type ILocationManager, which is a system private class. The
 * right way to create an instance of this class is using the
 * factory Context.getSystemService.
 */
public LocationManager(Context context, ILocationManager service) {
    mService = service;
    mContext = context;
}

@hide 注释使构造函数远离 Javadoc,IDE 不会显示它。你可以read more about the @hide annotation in this SO Q and A

基本上,该类的设计目的是让您从Context 获取它,而不是自己实例化它。对于需要复杂(或特定于平台)配置的事情,这是一种相当常见的设计,您希望避免让用户处理。

请注意,@hide 注释及其处理特定于 Android。

这类似于 Builder 或 Factory 模式的工作方式,其中只有 builder/factory 类可以实例化对象,尽管通常使用 Java 中的私有或包私有构造函数来完成:

public class MyWidget
{
    private final Foo someObject; 
    // ... more stuff


    private MyWidget(Builder builder)
    {
        this.someObject = builder.someObject;
        // ... more stuff
    }

    public static class Builder
    {
        Foo someObject;

        public Builder() {}

        public Builder withFoo(Foo someObject)
        {
            this.someObject = someObject;
            return this;
        }

        public MyWidget build()
        {
            return new MyWidget(this);
        }
    }
}

调用如下:

MyWidget widget = new MyWidget.Builder().withFoo(someFoo).build();

【讨论】:

  • 非常感谢。我刚刚从那篇文章中学到了很多东西。非常感谢。
  • @SpaceGhost 真实故事;我也是。我只玩过一点Android,并且期待构造函数是私有或包私有的标准习语 - 这是我在查看源代码之前期望输入的答案.这实际上是我对 Android 不了解的一件有趣的事情 :)
  • 是的,哈哈。我觉得问起来很愚蠢,但回想起我对 java 的了解,这让我有点难过。我使用了谷歌,但没有太多的空闲时间,所以我点击的每个链接都没有得到答案。自我提醒:下次看源码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多