Некоторые люди спрашивали: Как синглтон может вернуть нулевой указатель? Я отвечаю на этот вопрос. (Я не могу ответить в комментарии, потому что мне нужно отправить код.)
Он может возвращать нуль между двумя событиями: (1) класс загружен и (2) объект этого класса создается. Вот пример:
class X {
static X xinstance;
static Y yinstance = Y.yinstance;
X() {xinstance=this;}
}
class Y {
static X xinstance = X.xinstance;
static Y yinstance;
Y() {yinstance=this;}
}
public class A {
public static void main(String[] p) {
X x = new X();
Y y = new Y();
System.out.println("x:"+X.xinstance+" y:"+Y.yinstance);
System.out.println("x:"+Y.xinstance+" y:"+X.yinstance);
}
}
Бежим код:
$ javac A.java
$ java A
x:[email protected] y:[email protected]
x:null y:null
Вторая строка показывает, что Y.xinstance и X.yinstance являются нуль; они являются нулевыми, поскольку переменные X.xinstance ans Y.yinstance были прочитаны, когда они были пустыми.
Можно ли это исправить? Да,
class X {
static Y y = Y.getInstance();
static X theinstance;
static X getInstance() {if(theinstance==null) {theinstance = new X();} return theinstance;}
}
class Y {
static X x = X.getInstance();
static Y theinstance;
static Y getInstance() {if(theinstance==null) {theinstance = new Y();} return theinstance;}
}
public class A {
public static void main(String[] p) {
System.out.println("x:"+X.getInstance()+" y:"+Y.getInstance());
System.out.println("x:"+Y.x+" y:"+X.y);
}
}
и этот код не показывают аномалии:
$ javac A.java
$ java A
x:[email protected] y:[email protected]
x:[email protected] y:[email protected]
НО это не вариант для объекта Android Application
: программист не контролирует время, когда он будет создан.
Еще раз: разница между первым примером и вторым заключается в том, что второй пример создает экземпляр, если статический указатель имеет значение null. Но программист не может создать объект приложения Android, прежде чем система решит это сделать.
Просто разработать для других реализации этого, вы можете затем изменить ' 'вашего файла AndroidManifest.xml, чтобы включить следующее определение атрибута:' a ndroid: имя = "MyApp" '. MyApp должен быть в том же пакете, что и ваш манифест. –
Почему статический? Экземпляр приложения * всегда * создается раньше всего. Где бы вы ни ожидали получить доступ к контексту приложения, он будет передан вам в качестве аргументов. Такой подход может усложнить ваши тесты. Static-itis способствует общей связи. – mschonaker
УДИВИТЕЛЬНЫЙ способ обойти проблему предоставления контекста SQLiteOpenHelper! Я реализовал singleton «SQLiteManager» и застрял в «как F я получаю контекст для сингла?» –