Можете ли вы сказать нам, почему вы хотите определить глобальные переменные в Java?
Адам Пейнтер
44
Доступ к переменной из-за пределов класса
aTJ
5
Возможно, вам следует отредактировать свой вопрос, включив в него пример кода, иллюстрирующий именно то, что вы хотите. Это поможет нам порекомендовать лучшее решение.
Адам Пейнтер
7
@ Адам: я должен быть в состоянии изменить значение переменной в одном классе из другого класса.
аи
2
Вы не В Java нет глобальных переменных.
маркиз Лорн
Ответы:
261
Для определения глобальной переменной вы можете использовать статическое ключевое слово
Будьте осторожны при этом - когда класс Global выгружается, переменные будут неопределенными null. Если вы продаете свое приложение, это произойдет рано или поздно, и вы будете искать ошибки везде, но не там ....
user387184
10
staticКлючевое слово делает переменные глобально доступной, при загруженном их класс.
sjas
22
О выгрузке классов: если существует какая-либо сильная цепочка ссылок от любого корня GC до экземпляра Global или его дочерних элементов или какая-либо ссылка времени компиляции из загруженного и не выгружаемого класса в Global, то объект Class относительно Global сильно достижимый, и, следовательно, так же ClassLoader, который загрузил Global; что делает невозможным выгрузку Global (поскольку выгрузка класса может произойти только после того, как GC полностью удалит любую сильную ссылку на ClassLoader, который загрузил данный класс). Если у вас нет ссылок вообще, как разгрузка может быть проблемой ???
Бруно Рейс
4
@Abi Я бы посоветовал вам переименовать ваш класс Globalв другое ( TestClass?), Чтобы у людей не сложилось впечатление, что существует такая вещь, как Globalключевое слово Java. Лучше в безопасности, чем потом сожалеть :)
Николас Ринаудо
53
Вы не Это по замыслу. Ты не должен делать это, даже если бы мог.
При этом вы можете создать набор открытых статических членов в классе с именем Globals.
Тогда каков лучший способ, которым я могу объявить константы, чтобы все методы класса могли получить к ним доступ?
Олстон
6
Сообщения такого рода - причина, по которой новички разрабатывают глобальную переменную фобию, и затем мы видим, что разрабатываются всевозможные вопиющие методы, чтобы обойти табу глобальной переменной, но достичь того же эффекта.
Евгений Сергеев
40
Голосуй за то, чтобы сказать: «Не делай этого». без объяснения или ссылки на объяснение почему.
Джефф МакКьюн
4
@JeffMcCune: чтобы сделать ваше заявление более понятным, «не делайте этого» - это на самом деле фигня. Делай это, когда это полезно. Например, я должен отладить свой код с помощью некоторого IAbstractLoggerBullshit и, конечно, System.err не работает в этой сверхинженерной среде. Я не могу засорять свой код, передавая дерьмо логгера между сотнями бесполезных классов адаптеров.
Джо Со
6
Я собираюсь сделать это.
Плавающая солнечная
40
Другой способ - создать такой интерфейс:
publicinterfaceGlobalConstants{String name ="Chilly Billy";String address ="10 Chicken head Lane";}
Любой класс, который должен использовать их, должен только реализовать интерфейс:
Мне интересно, почему у этого ответа (до моего) нет повышающих голосов. Разве это не дает разумного альтернативного ответа на вопрос, который дают все остальные ответы?
M_M
12
«Эффективная Java» Джошуа Блоха, глава 4: Классы и интерфейсы, пункт 19: используйте интерфейсы только для определения типов «Постоянный шаблон интерфейса - это плохое использование интерфейсов». Эту книгу стоит прочитать! :)
MariuszS
1
Кроме того, из JDK 1.5+ вы можете использовать статический импорт для ваших глобальных переменных, реализация не требуется.
MariuszS
9
.... Правильно, это на самом деле ничего не объясняет, просто говорит, что в какой-то книге сказано, что это плохо.
linkhyrule5
14
Вот цитата для вас. Oracle говорит: «Чтобы обойти это, люди иногда помещают статические члены в интерфейс и наследуют от этого интерфейса. Это плохая идея. На самом деле, это настолько плохая идея, что для нее есть название: Constant Interface Antipattern (см. пункт «Эффективная Java» 17). Проблема в том, что использование классом статических членов другого класса является простой деталью реализации. Когда класс реализует интерфейс, он становится частью открытого API класса. Детали реализации не должны попадать в публичные API. "
Правда, хотя я думаю, что ваше использование "Globals" немного сбивает с толку :-). Что-то вроде «Параметры» было бы более подходящим, так как это не обязательно Global.
Марк Питерс
12
Множество хороших ответов, но я хочу привести этот пример, так как он считается более правильным способом доступа к переменным класса другим классом: с использованием методов получения и установки.
Причина, по которой вы используете геттеры и сеттеры таким образом, а не просто делаете переменную общедоступной, заключается в следующем. Допустим, ваш var будет глобальным параметром, который вы НИКОГДА не хотите, чтобы кто-то изменил во время выполнения вашей программы (в случае, когда вы разрабатываете код с командой), что-то вроде, возможно, URL-адреса веб-сайта. Теоретически это может измениться и может использоваться много раз в вашей программе, поэтому вы хотите использовать глобальную переменную, чтобы иметь возможность обновлять все сразу. Но вы не хотите, чтобы кто-то другой вошел и изменил эту переменную (возможно, даже не осознавая, насколько это важно). В этом случае вы просто не включаете метод установки, а только метод получения.
publicclassGlobal{privatestaticint var =5;publicstaticint getVar(){returnGlobal.var;}//If you do not want to change the var ever then do not include thispublicstaticvoid setVar(int var){Global.var = var;}}
Тем не менее, у нас есть staticключевое слово, и это все, что нам нужно. Ничто не существует вне класса в Java. staticКлючевое слово представляет собой переменный класс , который, в отличие от переменного экземпляра, имеет только одну копии и которая выходит за пределы во всех экземплярах этого класса , созданных, а это значит , что его значение может быть изменено и доступом во всех случаях , в любой момент.
Если вам нужна глобальная переменная, к которой можно получить доступ за пределами области действия, то эта переменная вам нужна, но ее область действия существует только там, где находится класс, и это будет все.
По правде говоря, нет понятия «ГЛОБАЛ» в Java-программе
Тем не менее, в вашем вопросе есть доля правды, потому что в некоторых случаях вы захотите запустить метод в любой части программы. Например, метод random () в приложении Phrase-O-Matic: этот метод должен вызываться из любой части программы.
Таким образом, для того, чтобы удовлетворить такие вещи, как Выше «Нам нужны глобальные переменные и методы»
ОБЪЯВИТЬ ПЕРЕМЕННОЕ ГЛОБАЛЬНЫМ.
1.Mark the variable as publicstaticfinalWhile declaring.
ОБЪЯВИТЬ МЕТОД КАК ГЛОБАЛЬНО .
1.Mark the method as publicstaticWhile declaring.
Поскольку я объявил глобальные переменные и метод как статические, вы можете вызывать их где угодно, просто с помощью следующего кода
ClassName.X
ПРИМЕЧАНИЕ . X может быть либо именем метода, либо именем переменной согласно требованию, а ClassName - это имя класса, в котором вы их объявили.
Убедитесь, что когда вы перемещаете свой код с пола режущей комнаты и в выпуске вы удаляете или комментируете эту функцию.
Если у вас есть метод рабочей лошадки, например, рандомизатор, я предлагаю создать пакет «Toolbox»! У всех кодеров должен быть один, тогда, когда вы захотите использовать его в .java, просто импортируйте его!
В Java нет такой вещи как действительно глобальная переменная. Каждая статическая переменная должна принадлежать какому-либо классу (например, System.out), но когда вы определили, в какой класс она будет входить, вы можете ссылаться на нее из любого места, загруженного одним и тем же загрузчиком классов.
Обратите внимание, что статические переменные всегда должны быть защищены при обновлении, чтобы избежать состояния гонки.
Java не предоставляет глобальную переменную функционально, но если вы хотите иметь концепцию глобальной переменной, мы можем использовать статическое ключевое слово
Abi
3
publicclassGlobalClass{publicstaticint x =37;publicstaticString s ="aaa";}
Таким образом, вы можете получить к ним доступ GlobalClass.xиGlobalClass.s
Как вы, вероятно, догадались из ответа, в Java нет глобальных переменных, и единственное, что вы можете сделать, - это создать класс со статическими членами:
publicclassGlobal{publicstaticint a;}
Вы можете использовать его в Global.aдругом месте. Однако, если вы используете Java 1.5 или выше, вы можете использовать import staticмагию, чтобы она выглядела еще более как настоящая глобальная переменная:
importstatic test.Global.*;publicclassUseGlobal{publicvoid foo(){int i = a;}}
И вуаля !
Теперь это далеко не лучшая практика, так что вы можете видеть в рекламе: не делайте этого дома
В Java нет глобальных переменных, но есть глобальные классы с открытыми полями. Вы можете использовать функцию статического импорта в Java 5, чтобы она выглядела почти как глобальные переменные.
Должна ли глобальная переменная быть конечной? Зачем?
Конерак
1
«окончательный» означает «постоянный», так что это глобальная константа.
duffymo
1
нет, вот что означает глобальная переменная, если вы хотите поделиться этой переменной и изменить данные, а затем просто удалить, finalно это, безусловно, зависит от того, как вы хотите поделиться, где вы используете и все,
Джигар Джоши
Какой тип CODEв этом примере? Где это определено?
M_M
Также обратите внимание: CODE присутствует во всех заглавных буквах, так как это обычная нотация Java для использования всех заглавных букв для переменных, которые вы объявляете как окончательные, и которые не предназначены для изменения в течение программы.
Дэн Сиборовский - MSFT
1
Создание независимого файла, например. Example.java, чтобы использовать 1-е решение, просто отлично. Вы можете сделать это также в приложении, если, например, глобальные переменные являются особенными для вашего текущего приложения и т. Д .:
Создайте класс в начале и объявите свои переменные там:
Вместо понижения голоса, скажите, пожалуйста, что не так с этим решением? Я использую это на постоянной основе, и это наиболее удобный. Так что я не могу поступить иначе, если рассматривать это отрицательное мнение как личную вещь или просто сделанное глупым человеком.
Апостолоса
1
Если вам нужно обновить глобальное свойство, в качестве глобальной переменной можно использовать простой класс-оболочку getter / setter. Типичный пример показан ниже.
Исходя из концепции, глобальные переменные, также известные как переменные экземпляра, являются переменными уровня класса, то есть они определены внутри класса, но вне методов. Чтобы сделать их полностью доступными и использовать их, предоставьте ключевое слово static. Так что, если я пишу программу для простой арифметической операции, и для нее требуется пара чисел, то две переменные экземпляра определяются следующим образом:
Более того, использование статического ключевого слова перед переменными экземпляра позволяет нам не указывать типы данных для одних и тех же переменных снова и снова. Просто напишите переменную напрямую.
В Java нет глобальных переменных; они также не известны как переменные экземпляра; определение их как « staticне делает их доступными полностью». Первый абзац это чепуха. Пример плохой практики.
маркиз Лорн
0
В общем, Java не имеет глобальных переменных. За исключением локальных переменных, все переменные входят в область действия любого класса, определенного в программе. Мы можем иметь статические переменные, чтобы иметь область видимости глобальных переменных.
Объектно-ориентированное программирование построено с пониманием того, что область видимости переменных тесно связана с объектом класса, который инкапсулирует эти переменные.
Проблема с созданием «глобальных переменных» заключается в том, что это не является отраслевым стандартом для Java. Это не отраслевой стандарт, поскольку он позволяет нескольким классам манипулировать данными асинхронно, если вы используете многопоточное приложение, это становится немного сложнее и опаснее с точки зрения безопасности потоков. Существуют и другие причины, по которым использование глобальных переменных неэффективно, но если вы хотите этого избежать, я предлагаю вам обратиться к аспектно-ориентированному программированию .
Аспектно-ориентированное программирование устраняет эту проблему, возлагая на родительский класс ответственность за область действия через что-то, называемое «советами», что добавляет дополнительное поведение к коду без его фактического изменения. Он предлагает решения для сквозных задач или использования глобальных переменных.
Spring - это Java-фреймворк, использующий AOP, и хотя он традиционно используется для веб-приложений, базовое приложение может использоваться повсеместно в Java-фреймворке (включая 8.0). Это может быть направление, которое вы хотите изучить больше.
Я рассматриваю квалификацию глобальной переменной как переменную, к которой можно обращаться и изменять в любом месте кода, не заботясь о статическом вызове / вызове экземпляра или передаче любой ссылки из одного класса в другой.
вам нужно будет иметь ссылку на экземпляр класса A и обновить значение в классе B следующим образом:
int initialValue =2;int newValue =3;
A a =new A(initialValue);
B b =new B();
b.passA(a);
b.changeMyVar(newValue);
assertEquals(a.getMyVar(),newValue);// true
Решение
Поэтому мое решение (даже если я не уверен, что это хорошая практика) - использовать синглтон:
Теперь вы можете получить уникальный экземпляр Global в любом месте с помощью:
Globals globals =Globals.getInstance();// and read and write to myVar with the getter and setter like int myVar = globals.getMyVar();
global.setMyVar(3);
// Get the access of global while retaining priveleges.// You can access variables in one class from another, with provisions.// The primitive must be protected or no modifier (seen in example).// the first classpublicclass farm{int eggs;// an integer to be set by constructor
fox afox;// declaration of a fox object// the constructor inits
farm(){
eggs =4;
afox =new fox();// an instance of a fox object// show count of eggs before the fox arrivesSystem.out.println("Count of eggs before: "+ eggs);// call class fox, afox method, pass myFarm as a reference
afox.stealEgg(this);// show the farm class, myFarm, primitive valueSystem.out.println("Count of eggs after : "+ eggs);}// end constructorpublicstaticvoid main(String[] args){// instance of a farm class object
farm myFarm =new farm();};// end main}// end class// the second classpublicclass fox{// theFarm is the myFarm object instance// any public, protected, or "no modifier" variable is accessiblevoid stealEgg(farm theFarm){--theFarm.eggs;}}// end class
Ответы:
Для определения глобальной переменной вы можете использовать статическое ключевое слово
теперь вы можете получить доступ к a и b из любого места, позвонив
источник
static
Ключевое слово делает переменные глобально доступной, при загруженном их класс.Global
в другое (TestClass
?), Чтобы у людей не сложилось впечатление, что существует такая вещь, какGlobal
ключевое слово Java. Лучше в безопасности, чем потом сожалеть :)Вы не Это по замыслу. Ты не должен делать это, даже если бы мог.
При этом вы можете создать набор открытых статических членов в классе с именем Globals.
но вы действительно не должны :). Серьезно .. не делай этого.
источник
Другой способ - создать такой интерфейс:
Любой класс, который должен использовать их, должен только реализовать интерфейс:
источник
Вам лучше использовать внедрение зависимостей:
источник
Множество хороших ответов, но я хочу привести этот пример, так как он считается более правильным способом доступа к переменным класса другим классом: с использованием методов получения и установки.
Причина, по которой вы используете геттеры и сеттеры таким образом, а не просто делаете переменную общедоступной, заключается в следующем. Допустим, ваш var будет глобальным параметром, который вы НИКОГДА не хотите, чтобы кто-то изменил во время выполнения вашей программы (в случае, когда вы разрабатываете код с командой), что-то вроде, возможно, URL-адреса веб-сайта. Теоретически это может измениться и может использоваться много раз в вашей программе, поэтому вы хотите использовать глобальную переменную, чтобы иметь возможность обновлять все сразу. Но вы не хотите, чтобы кто-то другой вошел и изменил эту переменную (возможно, даже не осознавая, насколько это важно). В этом случае вы просто не включаете метод установки, а только метод получения.
источник
В Java нет глобальной переменной
Тем не менее, у нас есть
static
ключевое слово, и это все, что нам нужно. Ничто не существует вне класса в Java.static
Ключевое слово представляет собой переменный класс , который, в отличие от переменного экземпляра, имеет только одну копии и которая выходит за пределы во всех экземплярах этого класса , созданных, а это значит , что его значение может быть изменено и доступом во всех случаях , в любой момент.Если вам нужна глобальная переменная, к которой можно получить доступ за пределами области действия, то эта переменная вам нужна, но ее область действия существует только там, где находится класс, и это будет все.
источник
По правде говоря, нет понятия «ГЛОБАЛ» в Java-программе
Тем не менее, в вашем вопросе есть доля правды, потому что в некоторых случаях вы захотите запустить метод в любой части программы. Например, метод random () в приложении Phrase-O-Matic: этот метод должен вызываться из любой части программы.
Таким образом, для того, чтобы удовлетворить такие вещи, как Выше «Нам нужны глобальные переменные и методы»
ОБЪЯВИТЬ ПЕРЕМЕННОЕ ГЛОБАЛЬНЫМ.
ОБЪЯВИТЬ МЕТОД КАК ГЛОБАЛЬНО .
Поскольку я объявил глобальные переменные и метод как статические, вы можете вызывать их где угодно, просто с помощью следующего кода
ClassName.X
ПРИМЕЧАНИЕ . X может быть либо именем метода, либо именем переменной согласно требованию, а ClassName - это имя класса, в котором вы их объявили.
источник
Ничто не должно быть глобальным, кроме констант.
Поместите это в свой основной класс. В других файлах .java используйте его через:
Убедитесь, что когда вы перемещаете свой код с пола режущей комнаты и в выпуске вы удаляете или комментируете эту функцию.
Если у вас есть метод рабочей лошадки, например, рандомизатор, я предлагаю создать пакет «Toolbox»! У всех кодеров должен быть один, тогда, когда вы захотите использовать его в .java, просто импортируйте его!
источник
В Java нет такой вещи как действительно глобальная переменная. Каждая статическая переменная должна принадлежать какому-либо классу (например, System.out), но когда вы определили, в какой класс она будет входить, вы можете ссылаться на нее из любого места, загруженного одним и тем же загрузчиком классов.
Обратите внимание, что статические переменные всегда должны быть защищены при обновлении, чтобы избежать состояния гонки.
источник
Таким образом, вы можете получить к ним доступ
GlobalClass.x
иGlobalClass.s
источник
Вы можете позвонить куда угодно
источник
Как вы, вероятно, догадались из ответа, в Java нет глобальных переменных, и единственное, что вы можете сделать, - это создать класс со статическими членами:
Вы можете использовать его в
Global.a
другом месте. Однако, если вы используете Java 1.5 или выше, вы можете использоватьimport static
магию, чтобы она выглядела еще более как настоящая глобальная переменная:И вуаля !
Теперь это далеко не лучшая практика, так что вы можете видеть в рекламе: не делайте этого дома
источник
В Java нет глобальных переменных, но есть глобальные классы с открытыми полями. Вы можете использовать функцию статического импорта в Java 5, чтобы она выглядела почти как глобальные переменные.
источник
Вообще Глобальная переменная (я полагаю, вы сравниваете ее с C, Cpp) определяют как
public static final
лайк
ENUM также полезны в таком сценарии:
Для примера
Calendar.JANUARY
)источник
final
но это, безусловно, зависит от того, как вы хотите поделиться, где вы используете и все,CODE
в этом примере? Где это определено?Создание независимого файла, например. Example.java, чтобы использовать 1-е решение, просто отлично. Вы можете сделать это также в приложении, если, например, глобальные переменные являются особенными для вашего текущего приложения и т. Д .:
Создайте класс в начале и объявите свои переменные там:
Затем вы можете получить доступ к этим переменным - используя их как «Globals.month_number» и т. Д. - из любого места в вашем приложении.
источник
Если вам нужно обновить глобальное свойство, в качестве глобальной переменной можно использовать простой класс-оболочку getter / setter. Типичный пример показан ниже.
источник
Исходя из концепции, глобальные переменные, также известные как переменные экземпляра, являются переменными уровня класса, то есть они определены внутри класса, но вне методов. Чтобы сделать их полностью доступными и использовать их, предоставьте ключевое слово static. Так что, если я пишу программу для простой арифметической операции, и для нее требуется пара чисел, то две переменные экземпляра определяются следующим образом:
Более того, использование статического ключевого слова перед переменными экземпляра позволяет нам не указывать типы данных для одних и тех же переменных снова и снова. Просто напишите переменную напрямую.
источник
static
не делает их доступными полностью». Первый абзац это чепуха. Пример плохой практики.В общем, Java не имеет глобальных переменных. За исключением локальных переменных, все переменные входят в область действия любого класса, определенного в программе. Мы можем иметь статические переменные, чтобы иметь область видимости глобальных переменных.
источник
без
static
этого тоже возможноисточник
Объектно-ориентированное программирование построено с пониманием того, что область видимости переменных тесно связана с объектом класса, который инкапсулирует эти переменные.
Проблема с созданием «глобальных переменных» заключается в том, что это не является отраслевым стандартом для Java. Это не отраслевой стандарт, поскольку он позволяет нескольким классам манипулировать данными асинхронно, если вы используете многопоточное приложение, это становится немного сложнее и опаснее с точки зрения безопасности потоков. Существуют и другие причины, по которым использование глобальных переменных неэффективно, но если вы хотите этого избежать, я предлагаю вам обратиться к аспектно-ориентированному программированию .
Аспектно-ориентированное программирование устраняет эту проблему, возлагая на родительский класс ответственность за область действия через что-то, называемое «советами», что добавляет дополнительное поведение к коду без его фактического изменения. Он предлагает решения для сквозных задач или использования глобальных переменных.
Spring - это Java-фреймворк, использующий AOP, и хотя он традиционно используется для веб-приложений, базовое приложение может использоваться повсеместно в Java-фреймворке (включая 8.0). Это может быть направление, которое вы хотите изучить больше.
источник
Понимание проблемы
Я рассматриваю квалификацию глобальной переменной как переменную, к которой можно обращаться и изменять в любом месте кода, не заботясь о статическом вызове / вызове экземпляра или передаче любой ссылки из одного класса в другой.
Обычно, если у вас есть класс А
и хотите получить доступ и обновить
myvar
в классе B,вам нужно будет иметь ссылку на экземпляр класса A и обновить значение в классе B следующим образом:
Решение
Поэтому мое решение (даже если я не уверен, что это хорошая практика) - использовать синглтон:
Теперь вы можете получить уникальный экземпляр Global в любом месте с помощью:
источник
источник
Для определения глобальной переменной вы можете использовать статическое ключевое слово
теперь вы можете получить доступ к a и b из любого места, позвонив
Yoy правы ... особенно в J2ME ... Вы можете избежать NullPointerException, поместив в свой конструктор MidLet (proggy initialization) эту строку кода:
Это гарантирует, что Инструменты будут размещены перед любой инструкцией, которая их использует.
Это оно!
источник