Ваш последний пример - тот, что с "public test () {int i = 0;}", вероятно, не будет работать как задумано. Перераспределив переменную «int» в test и addi, теперь у вас есть три переменные с именем «i»: переменная-член, определенная вверху, локальная переменная в test и другая локальная переменная в addi. Значение члена не изменяется ни одной из функций.
Я бы определенно избегал инициализации переменных фиктивными значениями, такими как ваш "contact1 = new String ()". Да, это предотвращает получение ошибки компиляции для неинициализированных переменных или, возможно, выдачи исключения нулевого указателя. Но если вы получите ошибку без этого, то это должно означать, что вы не смогли поместить реальное значение в переменную. Установка фиктивного значения не решает проблему, она просто скрывает ее. Это как наклеить ленту на сигнальную лампу на приборной панели: да, вы больше не видите предупреждение, но это не потому, что проблема устранена, а только потому, что вы ее скрыли.
Есть действительно случаи, когда имеет смысл установить значение по умолчанию, и тогда, возможно, вы замените его на какое-то другое значение, а может, и нет. Я не говорю, что это плохая практика. Я говорю, что если вы получаете ошибки для унифицированных переменных, не слепо инициализируйте их чем-то бессмысленным. Выясните, почему они не имеют значения, и решите реальную проблему.
Кроме того, я не уверен, что сказать о вашем примере. Я не уверен, что вы пытаетесь достичь. У вас есть переменные с именами contact1, contact2 и contact3, которые, кажется, никогда не используются. contactArray, по-видимому, должен быть заполнен fillContactsGui, но я не вижу, где он когда-либо вызывался. Я не уверен, являются ли это недостатками вашей логики или это просто неполный пример.
Что касается общего правильного способа инициализации и использования данных:
Если переменная может быть локальной, сделайте ее локальной. В этом случае идеально инициализируйте его в тот момент, когда вы его объявите. Как:
public void foobar()
{
... do some stuff ...
int i=0;
... do other stuff ...
i=i+j;
... etc ...
}
Я бы избегал его определения, а затем, если это возможно, позже инициализировал бы его, потому что это создает вероятность того, что вы не сможете его инициализировать. Конечно, если его можно инициализировать двумя различными способами, этого трудно избежать. Как:
public void foobar()
{
int i;
if (plugh>0)
i=plugh;
... bunch more logic ...
// Inside some IF so we won't even get here if i was set earlier
if (zork==true)
i=shambar;
... etc ...
}
Тем не менее, чем больше вы можете держать это вместе, тем лучше.