Variáveis ​​globais em Java

217

Como você define variáveis ​​globais em Java?

aTJ
fonte
20
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

public class Example {
    public static int a;
    public static int b;
}

agora você pode acessar aeb de qualquer lugar chamando

Example.a;

Example.b;
Abi
fonte
6
"Global" é o nome da classe.
Jerome
12
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.

public class Globals {
   public static int globalInt = 0;
   ///
}

mas você realmente não deveria :). Sério .. não faça isso.

Mihai Toader
fonte
6
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:

public interface GlobalConstants
{
  String name = "Chilly Billy";
  String address = "10 Chicken head Lane";
}

Qualquer classe que precise usá-los apenas precisará implementar a interface:

public class GlobalImpl implements GlobalConstants
{
  public GlobalImpl()
  {
     System.out.println(name);
  }
}
Evan Lévesque
fonte
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 ".
Jolta
23

É melhor usar a injeção de dependência:

public class Globals {
    public int a;
    public int b;
}

public class UsesGlobals {
    private final Globals globals;
    public UsesGlobals(Globals globals) {
        this.globals = globals;
    }
}
Peter Lawrey
fonte
5
É 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.

public class Global{
    private static int var = 5;

    public static int getVar(){
        return Global.var;
    }

    //If you do not want to change the var ever then do not include this
    public static void setVar(int var){
        Global.var = var;
    }
}
Dan Ciborowski - MSFT
fonte
10

Não há variável global em Java

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.

Nishant
fonte
9

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 public static final While declaring.

DECLARAR UM MÉTODO COMO GLOBAL .

 1. Mark the method as public static While 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.

JAVA
fonte
9

Nada deve ser global, exceto as constantes.

public class MyMainClass {
    public final static boolean DEBUGMODE=true;
}

Coloque isso na sua classe principal. Em outros arquivos .java, use-o através de:

if(MyMainClass.DEBUGMODE) System.out.println("Some debugging info");

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!

David Bowman
fonte
5

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.

Thorbjørn Ravn Andersen
fonte
1
java não fornece variável global funcionalmente, mas se você quiser ter um conceito de variável global, podemos fazer uso da palavra
Abi
3
public class GlobalClass {
     public static int x = 37;
     public static String s = "aaa";
}

Dessa forma, você pode acessá-los com GlobalClass.xeGlobalClass.s

Mark Baijens
fonte
2
public class GlobalImpl {   

 public static int global = 5;

}

você pode ligar para onde quiser:

GlobalImpl.global // 5

fonte
1

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:

public class Global {
    public static int 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:

import static test.Global.*;

public class UseGlobal {
    public void 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

gabuzo
fonte
1

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.

fastcodejava
fonte
1

Geralmente, a variável global (suponho que você a esteja comparando com C, Cpp) define como public static final

gostar

class GlobalConstant{
    public static final String CODE  = "cd";
}

ENUMs também são úteis nesse cenário:

Por exemplo Calendar.JANUARY)

Jigar Joshi
fonte
Uma variável global precisa ser final? Por quê?
precisa saber é o seguinte
1
"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:

class Globals {
  static int month_number;
  static String month_name;
}

Você pode acessar essas variáveis ​​- usando-as como 'Globals.month_number', etc. - de qualquer lugar do seu aplicativo.

Apostolos
fonte
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.

public class GlobalHolder {

    private static final GlobalHolder INSTANCE = new GlobalHolder();

    private volatile int globalProperty;

    public static GlobalHolder getInstance() {
        return INSTANCE;
    }

    public int getGlobalProperty() {
        return globalProperty;
    }

    public void setGlobalProperty(int globalProperty) {
        this.globalProperty = globalProperty;
    }

    public static void main(String[] args) {
        GlobalHolder.getInstance().setGlobalProperty(10);
        System.out.println(GlobalHolder.getInstance().getGlobalProperty());
    }
}
Turkdogan Tasdelen
fonte
0

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:

public class Add {
    static int a;
    static int b; 
    static int c;

    public static void main(String arg[]) {
        c=sum();
        System.out.println("Sum is: "+c); 
    }

    static int sum() {
       a=20;
       b=30;
       return a+b;   
    }
}

Output: Sum is: 50

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.

BIJAY
fonte
1
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.

principiante
fonte
0

sem staticisso também é possível:

class Main {
  String globalVar = "Global Value";

  class Class1 {
    Class1() {
      System.out.println("Class1: "+globalVar);
      globalVar += " - changed";
  } }
  class Class2 {
    Class2() {
      System.out.println("Class2: "+globalVar);
  } }

  public static void main(String[] args) {  
    Main m = new Main();
    m.mainCode();
  }
  void mainCode() {
    Class1 o1 = new Class1();
    Class2 o2 = new Class2();
  }
}

/*
Output:
Class1: Global Value
Class2: Global Value - changed
*/
zemiak
fonte
0

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.

sheepiiHD
fonte
0

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

public class A {
    private int myVar;

    public A(int myVar) {
        this.myVar = myVar;
    }

    public int getMyVar() {
        return myVar;
    }

    public void setMyVar(int mewVar) {
        this.myVar = newVar;
    }
}

e deseja acessar e atualizar myvarem uma classe B,

public class B{

    private A a;

    public void passA(A a){
        this.a = a;
    }

    public void changeMyVar(int newVar){
        a.setMyvar(newVar);
    }
}

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:


public class Globals {
    private static Globals globalsInstance = new Globals();

    public static Globals getInstance() {
        return globalsInstance;
    }

    private int myVar = 2;

    private Globals() {
    }

    public int getMyVar() {
        return myVar;
    }

    public void setMyVar(int myVar) {
        this.myVar = myVar;
    }
}

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);
Mendrika Sandratra
fonte
-1
// 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 class
public class 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 arrives
    System.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 value
    System.out.println("Count of eggs after : " + eggs);

  } // end constructor

  public static void main(String[] args){

    // instance of a farm class object
    farm myFarm = new farm();

  }; // end main

} // end class

// the second class
public class fox{

  // theFarm is the myFarm object instance
  // any public, protected, or "no modifier" variable is accessible
  void stealEgg(farm theFarm){ --theFarm.eggs; }

} // end class
Matt Thomas
fonte
2
O que essa resposta acrescenta que as outras respostas não? Não consigo ver nenhum valor "novo" nesta resposta.
EWit
-2

Para definir a variável global, você pode usar palavras-chave estáticas

public final class Tools {
  public static int a;
  public static int b;
}

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:

new Tools();

Isso garante que as Ferramentas sejam alocadas antes de qualquer instrução que as utilize.

É isso aí!

user2616742
fonte
3
Um ... Desculpe, mas o que isso adiciona que ainda não está coberto pelas respostas existentes?
Mysticial
Talvez você esteja certo ... mas esta resposta explica coisas como alocação de memória.
user2616742
Não há classes de nível superior estáticos em java
Andremoniy