Как создавать глобальные переменные
Глобальные переменные — это переменные, которые доступны отовсюду в приложении. Иначе говоря их область видимости — все приложение. Чтобы создать такую переменную в Java, необходимо в публичном классе создать публичную статическую переменную:
public class Example {
public static int a;
public static int b;
public static String str;
}
Переменные a
, b
и str
— стали глобальными. Мы можем получить к ним прямой доступ из других классов внутри приложения:
public class GlobalVarsDemo {
public static void main(String[] args) {
Example.a = 4;
Example.b = 5;
Example.str = "Global String variable value";
System.out.println(Example.a);
System.out.println(Example.b);
System.out.println(Example.str);
}
}
Если мы запустим метод main
, то увидим следующий вывод:
4
5
Global String variable value
Глобальные переменные можно разделить на 2 типа:- переменные которые можно редактировать;
- переменные, которые можно только считывать.
final
и присвоить ей значение при определении переменной:
public class Constants {
public static final double PI = 3.1415926535897932384626433832795;
public static final String HELLO_WORLD_STR = "Hello, World!";
}
По соглашению об именовании в ЯП Java, все константы нужно именовать в верхнем регистре, разделяя слова символом нижнего подчеркивания.
Итак, мы создали константы, и теперь мы не сможем изменять их значения:Однако, мы можем считывать их значения:
public class HelloWorld {
public static void main(String[] args) {
System.out.println(Constants.HELLO_WORLD_STR);
}
}
Вывод:
Hello, World!
public class ConstantsDemo {
public static void main(String[] args) {
double r = 10;
String message = String.format("Площадь круга с радиусом %f=%f", r, getCircleSquare(r));
System.out.println(message);
}
static double getCircleSquare(double r) {
return Constants.PI * r * r;
}
}
Вывод:
Площадь круга с радиусом 10,000000=314,159265
Стоит ли использовать глобальные переменные
В интернете много статей, основной посыл которых такой: глобальные переменные — это зло, плохо и ужасно. Так ли это на самом деле? Попробуем привести плюсы и минусы глобальных переменных, чтобы каждый мог сделать вывод самостоятельно.Начнем с минусов. Представим себе приложение, в котором есть класс с глобальными переменными, доступными для чтения и редактирования. Со временем в проекте растет количество классов, количество глобальных переменных и методов, которые используют глобальные переменные, а иными словами — зависят от них. Со временем каждая глобальная переменная считывается в разных частях системы для разных целей. В разных частях системы значение переменной может обновляться. Общая картина мира данного приложения существенно усложняется, и отсюда вытекают такие минусы:- Снижение читабельности и увеличение сложности понимания кода.
- Увеличение сложности сопровождения кода.
- Для изменения одной глобальной переменной, необходимо проанализировать весь код, чтобы не задать переменной невалидное для других частей системы значение.
- Увеличение ошибок, которые очень сложно отлаживать.
Представим себе глобальную переменную, массив объектов. В одной части системы в данном массиве ожидаются например строки, а в другой части системы кто-то решил использовать числа с плавающей точкой. Вряд ли кому-то захочется в таком разбираться.
- Имена переменных могут совпасть, если вы используете в своем коде глобальные переменные, а также некоторые библиотеки, в которых в свою очередь также используются глобальные переменные. Это может привести к ошибкам как на стороне вашего приложения, так и на стороне используемой вами библиотеки.
- Увеличивается связность между различными частями системы, которые используют глобальные переменные. Стремиться нужно наоборот к слабой связанности кода. Лучше иметь много маленьких подсистем, слабо связанных друг с другом, чем одну здоровенную фиговину. Потому что мозгу легче разбираться с несколькими простыми вещами, чем с одной слишком сложной и запутанной штукой.
- Написание юнит-тестов усложняется, поскольку тесту не известно, какие глобальные переменные нужны и каким образом их необходимо проинициализировать.
- В многопоточных приложениях использование глобальных переменных разными потоками приводит к росту ошибок, которые сложно отлаживать, и к росту сложности проекта. Из-за этого необходимо настраивать доступ к таким переменным более правильно, обвешивая их синхронизациями и блокировками. В будущем это может привести к замкнутым блокировкам. Например, поток А заблокировал для своей работы переменную X, а поток B заблокировал для своей работы переменную Y, а потоку А теперь нужна переменная Y, а потоку B переменная X. В итоге, программа зависнет.
- В маленьких проектах глобальные переменные — наиболее простая вещь для достижения работоспособности проекта.
- Иногда страх использования глобальных переменных приводит к еще большему усложнению проекта. Тогда программисты начинают создавать синглтоны и прибегать к прочим шаблонам проектирования.
- В программировании часто бывает нужно опираться на некоторые неизменные значения.
Самое разумное — записать такие значения в виде константы, потому что только константы дают гарантию, что значение переменной не изменится со временем. Такие константы можно встретить сплошь и рядом (
Integer.MAX_VALUE
,Integer.MIN_VALUE
,Boolean.TRUE
,Collections.EMPTY_LIST
и пр.). Но программирование не ограничивается использованием стандартных библиотек. Часто бывает нужно писать какую то уникальную логику, в которой необходимо будет опираться на свои, уникальные константы. Поэтому порой использование констант (глобальных переменных, доступных только для чтения) действительно упрощает жизнь.
- Все, что пишет начинающий разработчик — по сути небольшой проект. И использование в его проектах глобальных переменных приучит его к использованию глобальных переменных везде.
- Лучше научиться сначала обходиться без «запретных приемчиков». А с опытом понимание, когда такие приемчики уместно применять, придет само.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ