Ссылка на статический объект, созданный в одном классе во всем приложении - PullRequest
7 голосов
/ 22 ноября 2011

У меня есть Java-приложение, которое создает два статических объекта в базовом классе, эти объекты должны ссылаться на все классы в программе.

public class Baseclass{
    public static ClassA A = new ClassA();
    public static ClassB B = new Classb();
    ...
    ...
    ...
}   

Эти объекты упоминаются в других классах как локальные частные переменные.

public class ClassA{
    private ClassB b = Baseclass.B;

Однако оба объекта требуют друг друга для функционирования, и если я создаю новый экземпляр одного из объектов до того, как другой будет создан, локальной переменной в «верхних» классах присваивается значение NULL. Есть ли в Java какие-либо концепции, которые ссылались бы на реальный объект (например, указатель) на объект как на переменную, а не делали копию объекта?

Ответы [ 5 ]

8 голосов
/ 22 ноября 2011

Однако оба объекта требуют друг друга для функционирования, и если я создаю новый экземпляр одного из объектов до того, как другой будет создан, локальной переменной в «верхних» классах присваивается значение null.

Я думаю, что ответ, который вы ищете, - это «шаблон синглтона». Здесь вы создаете только один экземпляр класса для использования в других местах. Вот хорошая ссылка для чтения . Вот страница википедии с некоторыми примерами Java.

Итак, ваш код будет выглядеть примерно так:

public class A {
    private final static A instance = new A();

    /* private constructor forces you to use the getInstance() method below */
    private A() {}

    public static A getInstance() {
      return instance;
    }
}

Тогда, где бы вы ни хотели получить экземпляр A, вы должны сделать что-то вроде:

public class B {
    private final A classA = ClassA.getInstance();
    ...
}

Нет причины, по которой A не мог бы также иметь экземпляр B и вызывать методы B в своих собственных методах. Что вы не можете сделать с этой перекрестной зависимостью, так это вызвать любой другой метод в конструкторе.

В общем, кстати, эти шаблоны следует использовать с осторожностью. Лучший способ добиться этого - внедрение зависимостей вместо глобальных ссылок. Поперечная инъекция возможна, но опять же, она должна использоваться экономно. Лучшим решением было бы реорганизовать классы, чтобы они имели линейные зависимости.

Есть ли в Java какие-либо концепции, которые ссылались бы на фактический объект (например, указатель) на объект как на переменную, а не делали копию объекта?

Java передается по значению, но значение любого объекта является ссылкой на объект (аналогично указателям в C, хотя они не адрес памяти). Таким образом, если у вас есть экземпляр A и вы присвоите его другому полю, это поле будет иметь то же значение и будет ссылаться на тот же экземпляр A.

// instantiate a new instance of A
A a1 = new A();
// assign the reference to A to another variable
a2 = a1;
// they are equivalent and both reference the same object
if (a1 == a2) ...
1 голос
/ 22 ноября 2011

Когда вы делаете ссылку в Java, вы фактически делаете копию ссылки.Вы не копируете Baseclass.B в вашем примере.Вы копируете ссылку в Baseclass.B.

. В приведенном вами примере кода b будет иметь значение null, пока не будет определено Baseclass.B.Если вам нужно выполнить операцию на b, вы не можете сделать это в объявлении ClassA.Это нужно сделать в методе, который вызывается после создания объекта a.

1 голос
/ 22 ноября 2011

Существуют ли в Java какие-либо концепции, которые ссылались бы на фактический объект (например, указатель) на объект как переменную вместо создания копии объекта?

На самом деле Java имеет только ссылок. Переменная не может содержать объект, поэтому не стоит беспокоиться.

Кроме того, вместо выполнения

private ClassB b = Baseclass.B;

Я бы посоветовал вам рассмотреть возможность статического импорта:

import static some.package.Baseclass.*;
0 голосов
/ 22 ноября 2011

Есть ли в Java какие-либо концепции, которые ссылались бы на фактический объект (например, указатель) на объект как на переменную, а не делали копию объекта?

Когда вы делаетеthis:

private ClassB b = Baseclass.B;

На самом деле вы работаете с этим же объектом, потому что переменная "b" называется Reference Variable.

По вашему вопросу, я рекомендую сделать что-то вроде этого:

Первый инкапсулирует ссылку:

public class ClassA{
    private ClassB b;

    public void setB(ClassB b) {
        this.b = b;
    }

    public ClassB getB(ClassB b) {
        return this.b;
    }

}

Второй использует статический блок для инициализации переменных:

public class Baseclass{
    public static ClassA A = new ClassA();
    public static ClassB B = new Classb();
    static {
        A.setB(B);
        B.setA(A);
    }
} 
0 голосов
/ 22 ноября 2011

Это классическое приложение для синглтона.

Для каждого:

  • Сделайте конструктор приватным.
  • Добавить закрытый статический член класса собственного типа для хранения синглтон.
  • Добавить метод getThe (), который инициализирует вышеуказанный член, если он еще не установлен.

См. Википедия: шаблон Singleton .

Также создайте конструктор конструкции A, выполнив с ней getThe ().

Кроме того, не используйте открытые поля в Baseclass; вместо этого используйте общедоступные методы получения. Не храните отдельную переменную B; вместо этого попросите синглтон A для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...