I am trying to do some work with LocationManager class and saw that I cannot instantiate it.
It is not an abstract class and I was under the impression that only classes marked as abstract could not be instantiated.
For a more complete answer:
If you look at the source code for LocationManager, specifically line 303, you'll see it actually does have a public constructor ... but there's a special annotation:
/**
* @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;
}
The @hide
annotation keeps the constructor out of the Javadoc and the IDE won't show it. You can read more about the @hide annotation in this SO Q and A
Basically, the class is designed so that you get it from the Context
rather than instantiating it yourself. This is a fairly common design for things that require complex (or platform specific) configuration that you want to avoid having the user deal with.
Note that the @hide
annotation and its handling are specific to Android.
This is similar to how the Builder or Factory pattern works, where only a builder/factory class can instantiate the object, although usually that's done with a private or package-private constructor in 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);
}
}
}
Which gets invoked as:
MyWidget widget = new MyWidget.Builder().withFoo(someFoo).build();
Context#getSystemService(Context.LOCATION_SERVICE);