Javaのグローバル変数


217

Javaでグローバル変数をどのように定義しますか?


20
Javaでグローバル変数を定義する理由を教えてください。
Adam Paynter、2011年

44
クラスの外部から変数にアクセスするには
aTJ

5
おそらく、質問を編集して、必要なものを正確に示すサンプルコードを含める必要があります。それは私たちが最高のソリューションを推奨するのに役立ちます。
Adam Paynter、2011年

7
@Adam:あるクラスの変数の値を別のクラスから変更できるはずです。
aTJ

2
あなたはしません。Javaにはグローバル変数はありません。
ローン侯爵

回答:


261

グローバル変数を定義するには、静的キーワードを使用できます

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

これで、どこからでもaとbにアクセスできます。

Example.a;

Example.b;

6
「グローバル」はクラスの名前です。
ジェローム

12
これを行うときは注意してください。グローバルクラスがアンロードされると、変数は未定義のnullになります。アプリを販売した場合、これは遅かれ早かれ起こり、どこでもエラーを探し続けますが、そこにはありません...
user387184

10
staticそのクラスがロードされている間キーワードは、変数がグローバルにアクセスできるようになります。
sjas 2012年

22
クラスのアンロードについて:GCルートからグローバルまたはその子のインスタンスへの強い参照チェーン、またはロードされたアンロード不可能なクラスからグローバルへのコンパイル時参照がある場合、グローバルに対するClassオブジェクトは強くなります到達可能です。したがって、グローバルをロードしたClassLoaderも同様です。これにより、グローバルをアンロードすることが不可能になります(クラスのアンロードは、GCが、指定されたクラスをロードしたClassLoaderへの強い参照を完全に削除した後でのみ発生するため)。参照がまったくない場合、アンロードはどのように問題になりますか?
Bruno Reis

4
@Abi Javaキーワードのようなものがあるという印象を人々に与えないGlobalように、クラスの名前を別の名前(TestClass?)に変更することをお勧めしますGlobal。申し訳ありませんが安全です:)
Nicolas Rinaudo 2013

53

あなたはしません。これは仕様によるものです。できてもそれをするべきではありません。

そうは言っても、Globalsという名前のクラスに一連のパブリック静的メンバーを作成することができます。

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

しかし、あなたは本当にすべきではない:)。真剣に..それをしないでください。


6
次に、すべてのクラスメソッドが定数にアクセスできるように、定数を宣言できるより良いアプローチは何ですか?
Alston、2014年

6
この性質の投稿が、初心者がグローバル変数恐怖症を発症する理由であり、グローバル変数タブーを回避するために考案されたあらゆる種類の悪質な手法が見られますが、同じ効果が得られます。
Evgeni Sergeev 2015

38
「やめなさい」と言って反対票を投じてください。理由の説明を説明したり参照したりせずに。
Jeff McCune

4
@JeffMcCune:ステートメントをより明確にするために、「やらないでください」は実際にはでたらめです。必要に応じて実行してください。たとえば、いくつかのIAbstractLoggerBullshitを使用してコードをデバッグする必要がありますが、もちろんこの過剰設計された環境ではSystem.errは機能しません。何百もの役に立たないアダプタクラス間でロガーのがらくたをコードが散らかすことはできません。
Jo So

6
私がやります。
フローティングサンフィッシュ

40

別の方法は、次のようなインターフェースを作成することです。

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

それらを使用する必要があるクラスは、インターフェースを実装するだけです:

public class GlobalImpl implements GlobalConstants
{
  public GlobalImpl()
  {
     System.out.println(name);
  }
}

なぜこの答えには(私の前に)賛成票がないのかと思います。他のすべての回答によって提供されるものに対する合理的な代替回答を提供していませんか?
M_M '19

12
Joshua Blochによる効果的なJava、第4章:クラスとインターフェース、項目19:タイプを定義するためにのみインターフェースを使用する「定数インターフェースパターンはインターフェースの不適切な使用です。」この本は一読の価値があります!:)
MariuszS 2013

1
さらに、JDK 1.5以降では、グローバル変数に静的インポートを使用できます。実装は必要ありません。
MariuszS 2013

9
....そう、それは実際には何も説明していません。それは、一部の本がそれが悪いと言ったというだけです。
linkhyrule5 2013

14
ここにあなたのための引用があります。オラクルは言う:「これを回避するために、人々は時々インターフェースに静的メンバーを入れてそのインターフェースから継承します。これは悪い考えです。実際、その名前があることはとても悪い考えです:定数インターフェースアンチパターン(Effective Java Item 17を参照してください。)問題は、クラスの別のクラスの静的メンバーの使用が単なる実装の詳細であるということです。クラスがインターフェースを実装すると、それはクラスのパブリックAPIの一部になります。実装の詳細は、パブリックAPI。」
ジョルタ2015

23

依存性注入を使用するほうがよいです。

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

public class UsesGlobals {
    private final Globals globals;
    public UsesGlobals(Globals globals) {
        this.globals = globals;
    }
}

5
確かに、「グローバル」の使用は少し混乱していると思いますが:-)。「パラメーター」のようなものは、必ずしもグローバルではないため、より適切です。
Mark Peters

11

良い答えはたくさんありますが、別のクラスがクラスの変数にアクセスするためのより適切な方法である、ゲッターとセッターを使用するため、この例を挙げたいと思います。

変数を単にpublicにするのではなく、このようにゲッターとセッターを使用する理由は次のとおりです。あなたの変数が、あなたがプログラムの実行中に誰かに絶対に変更してほしくない(チームでコードを開発している場合)、おそらくウェブサイトのURLのようなグローバルパラメータになるとしましょう。理論的には、これは変更される可能性があり、プログラムで何度も使用される可能性があるため、グローバル変数を使用して一度に更新できるようにする必要があります。しかし、誰かがこの変数を変更することを望まないでしょう(おそらくそれがどれほど重要であるかを理解していない)。その場合は、setterメソッドを含めず、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;
    }
}

10

Javaにはグローバル変数はありません

それにもかかわらず、私たちが持っているのはstaticキーワードであり、それが私たちに必要なすべてです。Javaのクラス外には何も存在しません。staticキーワードは、インスタンス変数に反して、唯一のコピーとその値は任意の時点で、すべてのインスタンスに変更してアクセスすることができることを意味する作成そのクラスのすべてのインスタンス、横切ってその超越を有し、そのクラス変数を表します。

スコープを超えてアクセスできるグローバル変数が必要な場合、これは必要な変数ですが、そのスコープはクラスがある場所にのみ存在し、それですべてになります。


9

真に言えば、Java OOプログラムには「グローバル」の概念はありません。

それでも、プログラムの任意の部分でメソッドを実行したい場合があるため、質問の背後にいくつかの真実があります。たとえば、Phrase-O-Maticアプリのrandom()メソッドです。これは、プログラムのどこからでも呼び出すことができるメソッドです。

したがって、上記の「グローバルのような変数とメソッドが必要です」のようなものを満たすために

変数をグローバルとして宣言します。

 1.Mark the variable as public static final While declaring.

メソッドをグローバルとして宣言する

 1. Mark the method as public static While declaring.

グローバル変数とメソッドを静的として宣言したので、次のコードの助けを借りて、好きな場所で呼び出すことができます

ClassName.X

:Xは、要件に従ってメソッド名または変数名のいずれかであり、ClassNameは、それらを宣言したクラスの名前です。


9

定数を除いて、何もグローバルであってはなりません。

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

これをメインクラス内に配置します。他の.javaファイルでは、次のように使用します。

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

コードをカッティングルームの床から移動してリリースするときに、この機能を削除またはコメントアウトしてください。

ランダマイザーのような強力な方法がある場合は、「ツールボックス」パッケージを作成することをお勧めします。すべてのコーダーに1つ必要です。それを.javaで使用したいときはいつでもインポートしてください。


5

Javaには、真のグローバル変数などはありません。すべての静的変数は、何らかのクラス(System.outなど)に属している必要がありますが、どのクラスに入るかを決定したら、同じクラスローダーによってロードされたどこからでも参照できます。

競合状態を回避するために、更新時には静的変数を常に保護する必要があることに注意してください。


1
Javaは機能的にグローバル変数を提供しませんが、グローバル変数の概念が必要な場合は、静的キーワードを使用できます
Abi

3
public class GlobalClass {
     public static int x = 37;
     public static String s = "aaa";
}

このようにしてGlobalClass.x、およびでそれらにアクセスできますGlobalClass.s


2
public class GlobalImpl {   

 public static int global = 5;

}

あなたはどこにでも電話をかけることができます:

GlobalImpl.global // 5

1

おそらく回答から推測できるように、Javaにはグローバル変数はなく、実行できる唯一のことは、静的メンバーを持つクラスを作成することです。

public class Global {
    public static int a;
}

Global.a他の場所でも使用できます。ただし、Java 1.5以上を使用している場合は、import staticマジックを使用して、実際のグローバル変数としてさらに見栄えをよくすることができます。

import static test.Global.*;

public class UseGlobal {
    public void foo() {
        int i = a;
    }
}

そして、ほら

これはベストプラクティスとはほど遠いので、コマーシャルでわかるように、これを自宅で行わないでください。


1

Javaにはグローバル変数はありませんが、パブリックフィールドを持つグローバルクラスがあります。Java 5の静的インポート機能を使用して、ほとんどグローバル変数のように見せることができます。


1

一般的にグローバル変数(私はあなたがC、Cppと比較していると思います)は次のように定義します public static final

お気に入り

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

ENUMは、このようなシナリオでも役立ちます。

Calendar.JANUARY


グローバル変数はfinalである必要がありますか?どうして?
Konerak 2011年

1
「最終」は「定数」を意味するため、これはグローバル定数です。
duffymo 2011年

1
いいえ、それはグローバル変数がその変数を共有してデータを変更したい場合も同様に削除するfinalことを意味しますが、それは確かに共有したい方法、どこで使用しているかに依存します
Jigar Joshi

CODEこの例のタイプは何ですか?それはどこに定義されていますか?
M_M 2012

また、CODEはすべて大文字で表記されています。これは、Javaの一般的な表記法で、最終的に宣言する変数にすべて大文字を使用し、プログラムの途中で変更することを意図していないためです。
Dan Ciborowski-MSFT 2013年

1

独立したファイルを作成します。最初のソリューションを使用するExample.javaは問題ありません。たとえば、グローバル変数が現在のアプリに特別である場合などは、アプリ内でも行うことができます。

最初にクラスを作成し、そこで変数を宣言します。

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

その後、これらの変数に「Globals.month_number」などとして使用して、アプリのどこからでもアクセスできます。


反対投票の代わりに、このソリューションの何が問題になっているのか教えていただけますか?常時使用しており、最も便利です。ですから、私は、この反対票を個人的なものとして、または単に愚かな人によって行われたと見なすことはできません。
Apostolos 2017

1

グローバルプロパティを更新する必要がある場合は、単純なゲッター/セッターラッパークラスをグローバル変数として使用できます。以下に代表的な例を示します。

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());
    }
}

0

概念的に言うと、インスタンス変数とも呼ばれるグローバル変数は、クラスレベルの変数です。つまり、クラスの内部で定義されていますが、メソッドの外部では定義されていません。それらを完全に使用可能にし、それらを直接使用するには、staticキーワードを提供します。したがって、単純な算術演算用のプログラムを作成していて、数値のペアが必要な場合は、2つのインスタンス変数がそのように定義されます。

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

さらに、インスタンス変数の前にstaticキーワードを使用すると、同じ変数のデータ型を何度も指定する必要がなくなります。変数を直接書き込むだけです。


1
Javaにはグローバル変数はありません。それらはインスタンス変数としても知られていません。それらをstatic「完全に利用できるようにする」わけではないものとして定義します。最初の段落はナンセンスです。例は悪い習慣です。
ローン侯爵

0

一般に、Javaにはグローバル変数がありません。ローカル変数以外のすべての変数は、プログラムで定義されているクラスのスコープに含まれます。静的変数を使用して、グローバル変数のスコープを設定できます。


0

staticこれなしでも可能です:

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
*/

0

オブジェクト指向プログラミングは、変数のスコープがそれらの変数をカプセル化するクラスオブジェクトに密接に排他的であることを理解して構築されています。

「グローバル変数」を作成する際の問題は、Javaの業界標準ではないことです。複数のクラスで非同期にデータを操作できるため、業界標準ではありません。マルチスレッドアプリケーションを実行している場合、スレッドの安全性の点で少し複雑で危険になります。グローバル変数の使用が効果がない理由他にさまざまですが、それを回避したい場合は、アスペクト指向プログラミングを使用することをお勧めします。

アスペクト指向プログラミングは、「助言」と呼ばれるものを通してスコープを担当する親クラスを置くことによってこの問題を打ち消します。これは実際にコードを変更せずにコードに追加の動作を追加します。横断的な懸念やグローバル変数の使用に対するソリューションを提供します。

Springは、AOPを利用するJavaフレームワークであり、従来はWebアプリケーションで使用されていましたが、コアアプリケーションはJavaフレームワーク(8.0を含む)全体で普遍的に使用できます。これはあなたがもっと探求したい方向かもしれません。


0

問題を理解する

私は、グローバル変数の修飾を、静的/インスタンス呼び出しを気にしたり、あるクラスから別のクラスへの参照を渡したりすることなく、コード内のどこからでもアクセスおよび変更できる変数と見なしています。

通常、クラス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;
    }
}

myvarクラスBでアクセスして更新したい

public class B{

    private A a;

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

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

クラス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

解決

したがって、これに対する私の解決策は(たとえそれが良い習慣かどうかわからない場合でも)シングルトンを使用することです。


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;
    }
}

これで、グローバルな一意のインスタンスをどこでも取得できます。

Globals globals = Globals.getInstance();
// and read and write to myVar with the getter and setter like 
int myVar = globals.getMyVar();
global.setMyVar(3);

-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

2
この答えは、他の答えがそうではないことを何に追加しますか?この回答には「新しい」値はありません。
EWit 14

-2

グローバル変数を定義するには、静的キーワードを使用できます

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

これで、どこからでもaとbにアクセスできます。

Tools.a;
Tools.b;

Yoyは正解です。特にJ2MEの場合は、次のコード行をMidLetコンストラクター(プログレッシブ初期化)に入れることにより、NullPointerExceptionを回避できます。

new Tools();

これにより、ツールを使用する命令の前にツールが割り当てられます。

それでおしまい!


3
ええと...申し訳ありませんが、これは既存の回答でまだカバーされていない追加ですか?
Mysticial 2013

たぶん、あなたは正しいです。しかし、この答えはメモリ割り当てのようなものを説明します。
user2616742 2013

Javaには静的な最上位クラスはありません
Andremoniy 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.