Você pode nos dizer por que deseja definir variáveis globais em Java?
Adam Paynter
44
Para acessar a variável de fora da classe
aTJ
5
Talvez você deva editar sua pergunta para incluir algum código de exemplo que ilustra exatamente o que você deseja. Isso nos ajudaria a recomendar a melhor solução.
Adam Paynter
7
@ Adam: Eu deveria ser capaz de alterar o valor de uma variável em uma classe de outra classe.
precisa saber é
2
Você não Não há variáveis globais em Java.
Marquês de Lorne
Respostas:
261
Para definir a variável global, você pode usar palavras-chave estáticas
Tenha cuidado ao fazer isso - quando a classe Global for descarregada, as variáveis serão nulas indefinidas. Se você vender seu aplicativo isso vai acontecer mais cedo ou mais tarde e você manter a procura de erro em todos os lugares, mas não há ....
user387184
10
A staticpalavra-chave torna as variáveis acessíveis globalmente, enquanto sua classe é carregada.
sjas
22
Sobre o descarregamento de classe: se houver uma cadeia de referência forte de qualquer raiz do GC para uma instância da Global ou de seus filhos, ou qualquer referência em tempo de compilação de uma classe carregada e não descarregável para Global, o objeto Class relativo a Global será fortemente alcançável e, portanto, também é o ClassLoader que carregou Global; o que impossibilita o descarregamento global (já que o descarregamento de classe só pode ocorrer depois que o GC remove completamente qualquer referência forte ao ClassLoader que carregou uma determinada classe). Se você não tem nenhuma referência, como poderia ser um problema na descarga ???
Bruno Reis
4
@ Abi Sugiro que você renomeie sua classe de Globalpara outra coisa ( TestClass?) Para não dar às pessoas a impressão de que existe uma Globalpalavra-chave Java. Melhor prevenir do que remediar :)
Nicolas Rinaudo
53
Você não Isso é por design. Você não deveria fazer isso, mesmo que pudesse.
Dito isto, você pode criar um conjunto de membros estáticos públicos em uma classe chamada Globals.
Então, qual é a melhor abordagem que posso declarar constantes para que todos os métodos de classe possam acessá-las?
Alston
6
Postagens dessa natureza é a razão pela qual os novatos desenvolvem fobia de variável global e, em seguida, vemos todo tipo de técnicas flagrantes sendo criadas para contornar o tabu da variável global, mas atingindo o mesmo efeito.
Evgeni Sergeev
38
Vote para dizer "não faça". sem explicar ou se referir a uma explicação do porquê.
Jeff McCune
4
@JeffMcCune: para tornar sua declaração mais clara, "não faça" é realmente besteira. Faça quando for útil. Por exemplo, eu tenho que depurar meu código usando algumas IAbstractLoggerBullshit e, claro, o System.err não funciona nesse ambiente de engenharia excessiva. Não posso desarrumar meu código passando por aí entre centenas de classes de adaptadores inúteis.
Jo Então,
6
Eu estou indo fazer isso.
Sunfish flutuante
40
Outra maneira é criar uma interface como esta:
publicinterfaceGlobalConstants{String name ="Chilly Billy";String address ="10 Chicken head Lane";}
Qualquer classe que precise usá-los apenas precisará implementar a interface:
Eu estou querendo saber por que esta resposta tem (antes da minha) nenhum voto positivo. Não fornece uma resposta alternativa razoável à fornecida por todas as outras respostas?
M_M 19/08/12
12
Java efetivo de Joshua Bloch, Capítulo 4: Classes e Interfaces, Item 19: Use interfaces apenas para definir tipos "O padrão de interface constante é um uso inadequado de interfaces". Vale a pena ler este livro! :)
MariuszS
1
Além do JDK 1.5+, você pode usar a importação estática para suas variáveis globais, a implementação não é necessária.
MariuszS
9
.... Certo, isso não explica nada, apenas diz que algum livro disse que era ruim.
precisa saber é o seguinte
14
Aqui está uma cotação para você. A Oracle diz: "Para contornar isso, às vezes as pessoas colocam membros estáticos em uma interface e herdam dessa interface. É uma péssima idéia. Na verdade, é uma péssima idéia que exista um nome para isso: o Antipattern da Interface Constante (consulte Item Java Efetivo 17). O problema é que o uso de uma classe dos membros estáticos de outra classe é um mero detalhe de implementação. Quando uma classe implementa uma interface, ela se torna parte da API pública da classe. Os detalhes da implementação não devem vazar para APIs públicas ".
É verdade, embora eu ache que o uso de "Globals" confunda um pouco as coisas :-). Algo como "Parâmetros" seria mais adequado, pois não é necessariamente Global.
Mark Peters
11
Muitas respostas boas, mas quero dar esse exemplo, pois é considerado a maneira mais adequada de acessar variáveis de uma classe por outra classe: usando getters e setters.
A razão pela qual você usa getters e setters dessa maneira, em vez de apenas tornar a variável pública, é a seguinte. Digamos que seu var será um parâmetro global que você NUNCA deseja que alguém mude durante a execução do seu programa (no caso de você desenvolver código com uma equipe), algo como talvez o URL de um site. Em teoria, isso pode mudar e pode ser usado várias vezes no seu programa, então você deseja usar uma var global para poder atualizar tudo de uma vez. Mas você não quer que outra pessoa entre e mude esse var (possivelmente sem perceber o quanto é importante). Nesse caso, você simplesmente não inclui um método setter e inclui apenas o método getter.
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;}}
No entanto, o que temos é uma staticpalavra - chave e é tudo o que precisamos. Nada existe fora da classe em Java. A staticpalavra-chave representa uma variável de classe que, ao contrário da variável de instância, possui apenas uma cópia e transcende todas as instâncias dessa classe criada, o que significa que seu valor pode ser alterado e acessado em todas as instâncias a qualquer momento.
Se você precisar de uma variável global que possa ser acessada além dos escopos, esta é a variável que você precisa, mas seu escopo existe apenas onde a classe está e isso será tudo.
Na verdade, não há um conceito de "GLOBAL" em um programa Java OO
No entanto, há alguma verdade por trás de sua pergunta, porque haverá alguns casos em que você deseja executar um método em qualquer parte do programa. Por exemplo: --- método random () no aplicativo Phrase-O-Matic; é um método que deve ser chamado de qualquer lugar de um programa.
Portanto, para satisfazer as coisas como Acima "Precisamos ter variáveis e métodos do tipo Global"
DECLARAR UMA VARIÁVEL COMO GLOBAL.
1.Mark the variable as publicstaticfinalWhile declaring.
DECLARAR UM MÉTODO COMO GLOBAL .
1.Mark the method as publicstaticWhile declaring.
Como declarei variáveis e métodos globais como estáticos, você pode chamá-los para qualquer lugar que desejar, simplesmente com a ajuda do código a seguir
ClassName.X
NOTA : X pode ser o nome do método ou o nome da variável conforme o requisito e ClassName é o nome da classe na qual você os declarou.
Ao mover seu código para fora do piso da sala de corte, remova ou comente essa funcionalidade.
Se você tem um método de trabalho, como um randomizador, sugiro criar um pacote "Toolbox"! Todos os codificadores devem ter um, então sempre que você quiser usá-lo em um .java, apenas importe-o!
Não existe uma variável verdadeiramente global em Java. Toda variável estática deve pertencer a alguma classe (como System.out), mas quando você decidir em qual classe ela entrará, poderá consultá-la de qualquer lugar carregado pelo mesmo carregador de classe.
Observe que variáveis estáticas sempre devem ser protegidas durante a atualização para evitar condições de corrida.
Como você provavelmente adivinha pela resposta, não há variáveis globais em Java e a única coisa que você pode fazer é criar uma classe com membros estáticos:
publicclassGlobal{publicstaticint a;}
Você pode usá-lo com Global.aoutro lugar. No entanto, se você usa Java 1.5 ou superior, pode usar a import staticmágica para parecer ainda mais uma variável global real:
importstatic test.Global.*;publicclassUseGlobal{publicvoid foo(){int i = a;}}
E voilà !
Agora, isso está longe de ser uma prática recomendada, como você pode ver nos comerciais: não faça isso em casa
Não há variáveis globais em Java, mas existem classes globais com campos públicos. Você pode usar o recurso de importação estática do java 5 para parecer quase como variáveis globais.
"final" significa "constante", então essa é uma constante global.
duffymo
1
não, é para isso que variável global significa que se você deseja compartilhar essa variável e alterar os dados, basta remover, finalmas certamente depende de como você deseja compartilhar, onde está usando e tudo mais,
Jigar Joshi
Qual é o tipo CODEdeste exemplo? Onde é definido?
M_M
Observe também: CODE está em todas as maiúsculas, como sua notação java comum para usar todas as maiúsculas para variáveis que você declara como finais e não pretende mudar durante o curso de um programa.
Dan Ciborowski - MSFT
1
Criando um arquivo independente, por exemplo. Example.java para usar a 1ª solução, está bem. Você pode fazer isso também dentro do aplicativo, se, por exemplo, as variáveis globais forem especiais para o seu aplicativo atual, etc .:
Crie uma classe no início e declare suas variáveis:
Em vez de reduzir a votação, você pode me dizer o que há de errado com esta solução? Estou usando-o constantemente e é o mais conveniente. Portanto, não posso fazer de outra maneira isso, considerando esse voto negativo como algo pessoal ou apenas feito por uma pessoa estúpida.
Apostolos
1
Se você precisar atualizar a propriedade global, uma classe simples de wrapper getter / setter pode ser usada como variável global. Um exemplo típico é mostrado abaixo.
Seguindo o conceito, variáveis globais, também conhecidas como variável de instância, são as variáveis no nível da classe, ou seja, são definidas dentro de uma classe, mas fora de métodos. Para disponibilizá-los completamente e usá-los diretamente, forneça a palavra-chave estática. Portanto, se estou escrevendo um programa para operação aritmética simples e requer um par de números, duas variáveis de instância são definidas como:
Além disso, o uso de palavras-chave estáticas antes das variáveis de instância nos permite não especificar tipos de dados para as mesmas variáveis repetidamente. Basta escrever a variável diretamente.
Não há variáveis globais em Java; eles também não são conhecidos como variáveis de instância; defini-los como staticnão os "torna completamente disponíveis". O primeiro parágrafo é um disparate. Exemplo é má prática.
Marquês de Lorne
0
Em geral, Java não possui nenhuma variável global. Além das variáveis locais, todas as variáveis estão no escopo de qualquer classe definida no programa. Podemos ter variáveis estáticas para ter o escopo de variáveis globais.
A Programação Orientada a Objetos é criada com o entendimento de que o escopo das variáveis é estritamente exclusivo do objeto de classe que encapsula essas variáveis.
O problema com a criação de "variáveis globais" é que não é padrão da indústria para Java. Não é padrão do setor, pois permite que várias classes manipulem dados assincronizados; se você estiver executando um aplicativo multithread, isso fica um pouco mais complicado e perigoso em termos de segurança de thread. Existem várias outras razões pelas quais o uso de variáveis globais é ineficaz, mas se você quiser evitar isso, sugiro que você recorra à Programação Orientada a Aspectos .
A Programação Orientada a Aspectos nega esse problema, colocando a classe pai no comando do escopo por meio de algo chamado "conselhos", que adiciona comportamento adicional ao código sem realmente modificá-lo. Oferece soluções para preocupações transversais ou uso global de variáveis.
O Spring é uma estrutura Java que utiliza AOP e, embora seja tradicionalmente usada para aplicativos da Web, o aplicativo principal pode ser usado universalmente em toda a estrutura Java (8.0 incluída). Pode ser uma direção que você deseja explorar mais.
Considero a qualificação da variável global como uma variável que pode ser acessada e alterada em qualquer lugar do código sem se preocupar com a chamada estática / instância ou passando qualquer referência de uma classe para outra.
você precisará ter uma referência de uma instância da classe A e atualizar o valor na classe B assim:
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
Solução
Portanto, minha solução para isso (mesmo que eu não tenha certeza se é uma boa prática) é usar um singleton:
Agora você pode obter a instância exclusiva Global em qualquer lugar com:
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
agora você pode acessar aeb de qualquer lugar chamando
Tools.a;Tools.b;
Você está certo ... especialmente no J2ME ... Você pode evitar o NullPointerException colocando dentro do seu construtor MidLet (inicialização proggy) esta linha de código:
newTools();
Isso garante que as Ferramentas sejam alocadas antes de qualquer instrução que as utilize.
Respostas:
Para definir a variável global, você pode usar palavras-chave estáticas
agora você pode acessar aeb de qualquer lugar chamando
fonte
static
palavra-chave torna as variáveis acessíveis globalmente, enquanto sua classe é carregada.Global
para outra coisa (TestClass
?) Para não dar às pessoas a impressão de que existe umaGlobal
palavra-chave Java. Melhor prevenir do que remediar :)Você não Isso é por design. Você não deveria fazer isso, mesmo que pudesse.
Dito isto, você pode criar um conjunto de membros estáticos públicos em uma classe chamada Globals.
mas você realmente não deveria :). Sério .. não faça isso.
fonte
Outra maneira é criar uma interface como esta:
Qualquer classe que precise usá-los apenas precisará implementar a interface:
fonte
É melhor usar a injeção de dependência:
fonte
Muitas respostas boas, mas quero dar esse exemplo, pois é considerado a maneira mais adequada de acessar variáveis de uma classe por outra classe: usando getters e setters.
A razão pela qual você usa getters e setters dessa maneira, em vez de apenas tornar a variável pública, é a seguinte. Digamos que seu var será um parâmetro global que você NUNCA deseja que alguém mude durante a execução do seu programa (no caso de você desenvolver código com uma equipe), algo como talvez o URL de um site. Em teoria, isso pode mudar e pode ser usado várias vezes no seu programa, então você deseja usar uma var global para poder atualizar tudo de uma vez. Mas você não quer que outra pessoa entre e mude esse var (possivelmente sem perceber o quanto é importante). Nesse caso, você simplesmente não inclui um método setter e inclui apenas o método getter.
fonte
Não há variável global em Java
No entanto, o que temos é uma
static
palavra - chave e é tudo o que precisamos. Nada existe fora da classe em Java. Astatic
palavra-chave representa uma variável de classe que, ao contrário da variável de instância, possui apenas uma cópia e transcende todas as instâncias dessa classe criada, o que significa que seu valor pode ser alterado e acessado em todas as instâncias a qualquer momento.Se você precisar de uma variável global que possa ser acessada além dos escopos, esta é a variável que você precisa, mas seu escopo existe apenas onde a classe está e isso será tudo.
fonte
Na verdade, não há um conceito de "GLOBAL" em um programa Java OO
No entanto, há alguma verdade por trás de sua pergunta, porque haverá alguns casos em que você deseja executar um método em qualquer parte do programa. Por exemplo: --- método random () no aplicativo Phrase-O-Matic; é um método que deve ser chamado de qualquer lugar de um programa.
Portanto, para satisfazer as coisas como Acima "Precisamos ter variáveis e métodos do tipo Global"
DECLARAR UMA VARIÁVEL COMO GLOBAL.
DECLARAR UM MÉTODO COMO GLOBAL .
Como declarei variáveis e métodos globais como estáticos, você pode chamá-los para qualquer lugar que desejar, simplesmente com a ajuda do código a seguir
ClassName.X
NOTA : X pode ser o nome do método ou o nome da variável conforme o requisito e ClassName é o nome da classe na qual você os declarou.
fonte
Nada deve ser global, exceto as constantes.
Coloque isso na sua classe principal. Em outros arquivos .java, use-o através de:
Ao mover seu código para fora do piso da sala de corte, remova ou comente essa funcionalidade.
Se você tem um método de trabalho, como um randomizador, sugiro criar um pacote "Toolbox"! Todos os codificadores devem ter um, então sempre que você quiser usá-lo em um .java, apenas importe-o!
fonte
Não existe uma variável verdadeiramente global em Java. Toda variável estática deve pertencer a alguma classe (como System.out), mas quando você decidir em qual classe ela entrará, poderá consultá-la de qualquer lugar carregado pelo mesmo carregador de classe.
Observe que variáveis estáticas sempre devem ser protegidas durante a atualização para evitar condições de corrida.
fonte
Dessa forma, você pode acessá-los com
GlobalClass.x
eGlobalClass.s
fonte
você pode ligar para onde quiser:
fonte
Como você provavelmente adivinha pela resposta, não há variáveis globais em Java e a única coisa que você pode fazer é criar uma classe com membros estáticos:
Você pode usá-lo com
Global.a
outro lugar. No entanto, se você usa Java 1.5 ou superior, pode usar aimport static
mágica para parecer ainda mais uma variável global real:E voilà !
Agora, isso está longe de ser uma prática recomendada, como você pode ver nos comerciais: não faça isso em casa
fonte
Não há variáveis globais em Java, mas existem classes globais com campos públicos. Você pode usar o recurso de importação estática do java 5 para parecer quase como variáveis globais.
fonte
Geralmente, a variável global (suponho que você a esteja comparando com C, Cpp) define como
public static final
gostar
ENUMs também são úteis nesse cenário:
Por exemplo
Calendar.JANUARY
)fonte
final
mas certamente depende de como você deseja compartilhar, onde está usando e tudo mais,CODE
deste exemplo? Onde é definido?Criando um arquivo independente, por exemplo. Example.java para usar a 1ª solução, está bem. Você pode fazer isso também dentro do aplicativo, se, por exemplo, as variáveis globais forem especiais para o seu aplicativo atual, etc .:
Crie uma classe no início e declare suas variáveis:
Você pode acessar essas variáveis - usando-as como 'Globals.month_number', etc. - de qualquer lugar do seu aplicativo.
fonte
Se você precisar atualizar a propriedade global, uma classe simples de wrapper getter / setter pode ser usada como variável global. Um exemplo típico é mostrado abaixo.
fonte
Seguindo o conceito, variáveis globais, também conhecidas como variável de instância, são as variáveis no nível da classe, ou seja, são definidas dentro de uma classe, mas fora de métodos. Para disponibilizá-los completamente e usá-los diretamente, forneça a palavra-chave estática. Portanto, se estou escrevendo um programa para operação aritmética simples e requer um par de números, duas variáveis de instância são definidas como:
Além disso, o uso de palavras-chave estáticas antes das variáveis de instância nos permite não especificar tipos de dados para as mesmas variáveis repetidamente. Basta escrever a variável diretamente.
fonte
static
não os "torna completamente disponíveis". O primeiro parágrafo é um disparate. Exemplo é má prática.Em geral, Java não possui nenhuma variável global. Além das variáveis locais, todas as variáveis estão no escopo de qualquer classe definida no programa. Podemos ter variáveis estáticas para ter o escopo de variáveis globais.
fonte
sem
static
isso também é possível:fonte
A Programação Orientada a Objetos é criada com o entendimento de que o escopo das variáveis é estritamente exclusivo do objeto de classe que encapsula essas variáveis.
O problema com a criação de "variáveis globais" é que não é padrão da indústria para Java. Não é padrão do setor, pois permite que várias classes manipulem dados assincronizados; se você estiver executando um aplicativo multithread, isso fica um pouco mais complicado e perigoso em termos de segurança de thread. Existem várias outras razões pelas quais o uso de variáveis globais é ineficaz, mas se você quiser evitar isso, sugiro que você recorra à Programação Orientada a Aspectos .
A Programação Orientada a Aspectos nega esse problema, colocando a classe pai no comando do escopo por meio de algo chamado "conselhos", que adiciona comportamento adicional ao código sem realmente modificá-lo. Oferece soluções para preocupações transversais ou uso global de variáveis.
O Spring é uma estrutura Java que utiliza AOP e, embora seja tradicionalmente usada para aplicativos da Web, o aplicativo principal pode ser usado universalmente em toda a estrutura Java (8.0 incluída). Pode ser uma direção que você deseja explorar mais.
fonte
Compreendendo o problema
Considero a qualificação da variável global como uma variável que pode ser acessada e alterada em qualquer lugar do código sem se preocupar com a chamada estática / instância ou passando qualquer referência de uma classe para outra.
Normalmente, se você tem classe A
e deseja acessar e atualizar
myvar
em uma classe B,você precisará ter uma referência de uma instância da classe A e atualizar o valor na classe B assim:
Solução
Portanto, minha solução para isso (mesmo que eu não tenha certeza se é uma boa prática) é usar um singleton:
Agora você pode obter a instância exclusiva Global em qualquer lugar com:
fonte
fonte
Para definir a variável global, você pode usar palavras-chave estáticas
agora você pode acessar aeb de qualquer lugar chamando
Você está certo ... especialmente no J2ME ... Você pode evitar o NullPointerException colocando dentro do seu construtor MidLet (inicialização proggy) esta linha de código:
Isso garante que as Ferramentas sejam alocadas antes de qualquer instrução que as utilize.
É isso aí!
fonte