Когда вы говорите «вы застряли», вы имеете в виду, что вы получаете NullPointerException
с?
Переменные PointerToB
и PointerToC
являются статическими и действительно будут установлены конструктором ClassA
. Однако это будет выполняться только при создании экземпляра ClassA.
Вместо этого вы, вероятно, подумали о статическом блоке инициализации, который будет запускаться, когда класс загружен :
public class ClassA {
public static ClassB PointerToB;
public static ClassC PointerToC;
static {
PointerToB = new ClassB();
PointerToC = new ClassC();
}
public ClassA() {
PointerToB.doSthB();
}
}
Теперь, когда вы будете обращаться к этим переменным, они будут отличны от NULL. В данном конкретном случае, поскольку вы не делаете ничего сложного, вы можете также инициализировать их в объявлении:
public class ClassA {
public static ClassB PointerToB = new ClassB();
public static ClassC PointerToC = new ClassC();
}
Это функционально идентично, но, возможно, легче написать и понять.
Edit: В дополнение, обратите внимание, что ваш код на самом деле довольно неприятный, как сейчас - есть скрытая временная зависимость, в которой он будет работать правильно, пока какой-то фрагмент кода создает экземпляр ClassA перед вами Доступ к статическим переменным. Это могло бы сработать довольно счастливо (по совпадению) в течение нескольких месяцев, прежде чем кто-то внесет какое-то крошечное изменение (например, создаст ClassA по требованию, а не с нетерпением) и BANG, внезапно какой-то совершенно не связанный код начнет разрушаться.
Даже хуже, чем эта временная зависимость, вы открываете себя для условий гонки, которые вы, вероятно, даже не рассматривали. Обе мои версии выше гарантируют, что статические переменные инициализируются до того, как вы сможете что-либо делать в классе, но это не относится к вашей версии. Вы устанавливаете их каждый раз, когда создается класс. Если один поток вызывает конструктор, а другой поток обращается к переменной, результаты не определены и могут проявляться как "случайные" сбои, странные проблемы с данными или другие вещи.
Даже если вы избегаете этого, фактические ссылки на объекты со временем изменятся, поэтому вы можете вызвать что-то вроде PointerToC.doSthC()
(скажем, увеличивает счетчик в C) - это правильно сделает счетчик 1, но позже точка в программе, PointerToC
была сброшена на новый экземпляр ClassC
и счетчик снова обнулен!
Я не хочу показывать вам или что-то в этом роде, просто чтобы показать, как важно думать о проблемах согласованности данных - и как просто, потому что что-то компилируется, и даже если это работает (прямо сейчас) это не обязательно правильно .