Java'daki global değişkenler


217

Java'da Global değişkenleri nasıl tanımlıyorsunuz?


20
Java'da neden global değişkenleri tanımlamak istediğinizi söyleyebilir misiniz?
Adam Paynter

44
Değişkene sınıfın dışından erişmek için
aTJ

5
Belki de sorunuzu, tam olarak ne istediğinizi gösteren bazı örnek kodlar içerecek şekilde düzenlemelisiniz. En iyi çözümü önermemize yardımcı olur.
Adam Paynter

7
@Adam: Bir sınıftaki bir değişkenin değerini başka bir sınıftan değiştirebilmeliyim.
aTJ

2
Yapmazsın. Java'da genel değişken yoktur.
Lorne Marquis

Yanıtlar:


261

Global Değişken'i tanımlamak için statik Anahtar Kelimeyi kullanabilirsiniz

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

şimdi a ve b'ye istediğiniz yerden erişebilirsiniz

Example.a;

Example.b;

6
"Global" sınıfın adıdır.
Jerome

12
Bunu yaparken dikkatli olun - Global sınıf kaldırıldığında değişkenler tanımsız olacaktır. Uygulamanızı satıyorsanız, bu er ya da geç olur ve her yerde hata aramaya devam edersiniz ama orada değil ....
user387184

10
staticOnların sınıf yüklü iken anahtar kelime, genel erişilebilir hale getirir.
sjas

22
Sınıf boşaltma hakkında: herhangi bir GC Kökünden Global veya alt sürümlerine yönelik güçlü bir referans zinciri veya yüklü ve yüklenemeyen bir sınıftan Global'e herhangi bir derleme zamanı başvurusu varsa, Global'e göre Sınıf nesnesi güçlüdür ulaşılabilir ve dolayısıyla Global yüklenen ClassLoader da; Global'i kaldırmayı imkansız hale getirir (çünkü sınıfın boşaltılması ancak GC belirli bir sınıfı yükleyen ClassLoader'a güçlü bir referansı tamamen kaldırdıktan sonra gerçekleşebilir). Hiç referansınız yoksa, boşaltma nasıl bir sorun olabilir ???
Bruno Reis

4
@Abi İnsanlara Java anahtar kelimesi gibi bir şey olduğu izlenimini vermemek için sınıfınızı Globalbaşka bir şeye ( TestClass?) Yeniden adlandırmanızı öneririm Global. Üzgünüm daha güvenli :)
Nicolas Rinaudo

53

Yapmazsın. Bu tasarım gereğidir. Yapabilsen bile yapmamalısın.

Globals adlı bir sınıfta bir dizi genel statik üye oluşturabileceğiniz söyleniyor.

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

ama gerçekten yapmamalısın :). Cidden .. yapma.


6
Peki, tüm sınıf yöntemlerinin bunlara erişebilmesi için sabitleri bildirebileceğim en iyi yaklaşım nedir?
Alston

6
Bu tür mesajlar, acemilerin küresel değişken fobiyi geliştirmesinin sebebidir ve daha sonra küresel değişken tabudan kaçınmak, ancak aynı etkiyi elde etmek için her türlü acımasız tekniklerin geliştirildiğini görüyoruz.
Evgeni Sergeev

40
Aşağı oy, "yapma" dedi. nedenini açıklamadan ya da açıklamadan bahsetmeden.
Jeff McCune

4
@JeffMcCune: ifadenizi daha açık hale getirmek için "yapma" aslında saçmalıktır. Yararlı olduğunda yapın. Örneğin, bazı IAbstractLoggerBullshit kullanarak kodumu hata ayıklamak zorunda ve tabii ki System.err bu aşırı işlenmiş ortamda çalışmıyor. Yüzlerce işe yaramaz adaptör sınıfı arasında logger bok etrafında geçen kodumu çöp olamaz.
Jo So

6
Ben yapacağım.
Yüzen Güneş Balığı

40

Başka bir yol, böyle bir arayüz oluşturmaktır:

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

Bunları kullanması gereken herhangi bir sınıf yalnızca arabirimi uygulamalıdır:

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

Bu cevabın neden (benden önce) yukarı oy olmadığını merak ediyorum. Diğer tüm cevapların verdiği cevaba makul bir alternatif cevap vermiyor mu?
M_M

12
Etkili Java by Joshua Bloch, Bölüm 4: Sınıflar ve Arabirimler, Madde 19: Arabirimleri yalnızca türleri tanımlamak için kullanın "Sabit arabirim deseni, arabirimlerin zayıf kullanımıdır." Bu kitap okumaya değer! :)
MariuszS

1
Ek olarak JDK 1.5+ 'dan global değişkenleriniz için statik içe aktarma kullanabilirsiniz, uygulamaya gerek yoktur.
MariuszS

9
.... Doğru, bu aslında hiçbir şeyi açıklamıyor, sadece bazı kitapların kötü olduğunu söyledi.
linkhyrule5

14
İşte size bir teklif. Oracle şöyle diyor: "Bunu aşmak için, insanlar bazen statik üyeleri bir arayüze koyup bu arayüzden miras alıyorlar. Bu kötü bir fikir. Aslında, bunun için bir isim olması çok kötü bir fikir: Sabit Arayüz Antipattern (bkz. Etkili Java Öğesi 17.) Sorun, bir sınıfın başka bir sınıfın statik üyelerini kullanmasının yalnızca bir uygulama ayrıntısı olmasıdır. Bir sınıf bir arabirim uyguladığında, sınıfın genel API'sinin bir parçası haline gelir. herkese açık API'lar. "
Jolta

23

Bağımlılık enjeksiyonu kullanmaktan daha iyidir:

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

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

5
Doğru, ama "Globals" kullanımınız biraz karışık şeyler düşünüyorum :-). "Parametreler" gibi bir şey Global olması gerekmediği için daha uygun olacaktır.
Mark Peters

12

Çok iyi cevaplar, ama başka bir sınıf tarafından bir sınıfın değişkenlerine erişmek için daha uygun bir yol olarak kabul edilir: getters ve setters kullanarak bu örneği vermek istiyorum.

Değişkeni herkese açık hale getirmek yerine alıcıları ve ayarlayıcıları bu şekilde kullanmanızın nedeni aşağıdaki gibidir. Diyelim ki var'ınız, programınızın yürütülmesi sırasında (bir ekiple kod geliştirdiğinizde), bir web sitesinin URL'si gibi bir şeyin ASLA değiştirmesini istemediğiniz global bir parametre olacağını varsayalım. Teorik olarak bu değişebilir ve programınızda birçok kez kullanılabilir, bu yüzden hepsini bir kerede güncelleyebilmek için global bir değişken kullanmak istersiniz. Ama başka birisinin girip bu değişkeni değiştirmesini istemiyorsunuz (muhtemelen ne kadar önemli olduğunu fark etmeden). Bu durumda, bir ayarlayıcı yöntemi eklemez ve yalnızca alıcı yöntemini dahil edersiniz.

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'da genel bir değişken yok

Yine de, elimizde bir staticanahtar kelime var ve tek ihtiyacımız olan bu. Java sınıfının dışında hiçbir şey yok. staticKelime örnek değişkeni aksine, sadece tek bir kopya ve değeri herhangi bir noktada tüm örneklerinde değiştirilebilir ve ulaşılabilir olduğu anlamına gelir oluşturulan bu sınıfın her durumda, karşısındaki aşar vardır, bu bir sınıf değişkeni temsil eder.

Kapsamların ötesinde erişilebilen global bir değişkene ihtiyacınız varsa, bu ihtiyacınız olan değişkendir, ancak kapsamı yalnızca sınıfın olduğu yerde bulunur ve hepsi bu olur.


9

Gerçekten bir java OO programında "GLOBAL" kavramı yoktur

Bununla birlikte, sorunuzun arkasında bazı gerçekler vardır, çünkü programın herhangi bir bölümünde bir yöntem çalıştırmak istediğiniz bazı durumlar olacaktır. Örneğin, Phrase-O-Matic uygulamasında --- random () yöntemi; bir programın herhangi bir yerinden çağrılabilir bir yöntemdir.

Yani "Küresel-benzeri değişkenlere ve yöntemlere ihtiyacımız var"

DEĞİŞKEN KÜRESEL OLARAK BEYANMEK İÇİN.

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

BİR YÖNTEMİ KÜRESEL OLARAK BİLDİRMEK .

 1. Mark the method as public static While declaring.

Global değişkenleri ve metodu statik olarak beyan ettiğim için, sadece aşağıdaki kod yardımı ile bunları istediğiniz yere çağırabilirsiniz

ClassName.X

NOT : X, gereksinime göre yöntem adı veya değişken adı olabilir ve ClassName, bildirdiğiniz sınıfın adıdır.


9

Sabitler dışında hiçbir şey küresel olmamalıdır.

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

Bunu ana sınıfınıza koyun. Diğer .java dosyalarında şunu kullanarak kullanın:

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

Kodunuzu kesme odası tabanından kaldırdığınızda ve serbest bıraktığınızda, bu işlevi kaldırdığınızdan veya yorum yaptığınızdan emin olun.

Rastgele bir düzenleyici gibi bir çalışma yönteminiz varsa, bir "Araç Kutusu" paketi oluşturmanızı öneririm! Tüm kodlayıcıların bir tane olması gerekir, o zaman bir .java'da kullanmak istediğinizde, içe aktarın!


5

Java'da gerçekten küresel bir değişken diye bir şey yoktur. Her statik değişken bir sınıfa ait olmalıdır (System.out gibi), ancak hangi sınıfa gireceğine karar verdiğinizde, aynı sınıf yükleyici tarafından yüklenen her yerden ona başvurabilirsiniz.

Yarış koşullarından kaçınmak için güncelleme sırasında statik değişkenlerin her zaman korunması gerektiğini unutmayın.


1
java global değişkeni işlevsel olarak sağlamaz, ancak global bir değişken kavramına sahip olmak istiyorsanız, statik anahtar kelimeyi kullanabiliriz
Abi

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

Bu şekilde onlara GlobalClass.xveGlobalClass.s


2
public class GlobalImpl {   

 public static int global = 5;

}

istediğiniz herhangi bir yeri arayabilirsiniz:

GlobalImpl.global // 5

1

Muhtemelen cevaptan tahmin ettiğiniz gibi, Java'da küresel değişkenler yoktur ve yapabileceğiniz tek şey statik üyelerle bir sınıf oluşturmaktır:

public class Global {
    public static int a;
}

Global.aBaşka bir yerde kullanabilirsiniz . Bununla birlikte, Java 1.5 veya daha iyisini kullanıyorsanız, import staticsihri gerçek bir global değişken olarak daha da fazla göstermek için kullanabilirsiniz:

import static test.Global.*;

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

Ve voilà !

Şimdi bu, reklamlarda görebileceğiniz gibi en iyi uygulamalardan çok uzak: bunu evde yapma


1

Java'da genel değişken yoktur, ancak ortak alanlara sahip genel sınıflar vardır. Java 5'in statik içe aktarma özelliğini neredeyse global değişkenlere benzetmek için kullanabilirsiniz.


1

Genel olarak Global değişken (C, Cpp ile karşılaştırdığınızı varsayıyorum) public static final

sevmek

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

ENUM'lar bu senaryoda da yararlıdır:

Örneğin Calendar.JANUARY)


Küresel bir değişkenin nihai olması gerekiyor mu? Neden?
Konerak

1
"son" "sabit" anlamına gelir, dolayısıyla bu global bir sabittir.
duffymo

1
Hayır, bu değişkeni paylaşmak ve verileri değiştirmek istiyorsanız Global değişkenin anlamı nedir, o zaman sadece kaldırın, finalancak kesinlikle nasıl paylaşmak istediğinize, nerede kullandığınıza ve hepsine bağlıdır,
Jigar Joshi

CODEBu örnekteki türü nedir ? Nerede tanımlanır?
M_M

Ayrıca not: CODE tüm büyük harflerle yazılmıştır, çünkü ortak olarak java gösterimi, son olarak bildirdiğiniz değişkenler için tüm büyük harfleri kullanır ve bir program sırasında değiştirmek istemez.
Dan Ciborowski - MSFT

1

Bağımsız bir dosya oluşturma, ör. Örnek. 1. çözümü kullanmak için java, gayet iyi. Örneğin global değişkenler mevcut uygulamanıza özel ise, uygulama içinde de yapabilirsiniz.

Başlangıçta bir sınıf oluşturun ve orada değişkenlerinizi bildirin:

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

Daha sonra bu değişkenlere (Globals.month_number 'vb. Kullanarak) uygulamanızdaki her yerden erişebilirsiniz.


Aşağı oylama yerine, lütfen bu çözümde neyin yanlış olduğunu söyleyebilir misiniz? Bunu sürekli olarak kullanıyorum ve en uygun olanı. Bu yüzden, bu düşüşü kişisel bir şey olarak düşünerek veya sadece aptal bir kişi tarafından yapıldığını başka türlü yapamam.
Apostolos

1

Global özelliği güncellemeniz gerekiyorsa, global değişken olarak basit bir alıcı / ayarlayıcı sarmalayıcı sınıfı kullanılabilir. Tipik bir örnek aşağıda gösterilmiştir.

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

Kavrama göre, örnek değişken olarak da bilinen global değişkenler, sınıf düzeyi değişkenleridir, yani, bir sınıf içinde ancak dış yöntemler olarak tanımlanırlar. Bunları tamamen kullanılabilir hale getirmek ve kullanmak için doğrudan statik anahtar kelimeyi sağlayın. Yani basit aritmetik işlem için bir program yazıyorum ve bir sayı çifti gerektiriyorsa, iki örnek değişkenleri şöyle tanımlanır:

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

Ayrıca, örnek değişkenlerinden önce statik anahtar kelime kullanmak, aynı değişkenler için veri türlerini tekrar tekrar belirtmememizi sağlar. Değişkeni doğrudan yazmanız yeterlidir.


1
Java'da genel değişken yoktur; bunlar örnek değişkenleri olarak da bilinmemektedir; onları static'tamamen kullanılabilir hale getirmez' olarak tanımlamak . İlk paragraf saçmalıktır. Örnek kötü uygulama.
Lorne Marquis

0

Genel olarak, Java'nın global değişkenleri yoktur. Yerel değişkenler dışında, tüm değişkenler programda tanımlanan herhangi bir sınıfın kapsamına girer. Global değişkenlerin kapsamına sahip olmak için statik değişkenlere sahip olabiliriz.


0

staticbu olmadan da mümkündür:

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

Nesneye Yönelik Programlama , değişkenlerin kapsamının, bu değişkenleri kapsayan sınıf nesnesine çok özel olduğu anlayışıyla oluşturulmuştur.

"Global değişkenler" yaratmanın problemi Java için endüstri standardı olmamasıdır. Endüstri standardı değildir, çünkü birden fazla sınıfın verileri asenkronize olarak işlemesine izin verir, çok iş parçacıklı bir uygulama çalıştırıyorsanız, iş parçacığı güvenliği açısından biraz daha karmaşık ve tehlikeli hale gelir. Orada çeşitli diğer nedenler kullanarak küresel değişkenler etkisiz neden, ama o kaçınmak istiyorsanız, size çare önermek Aspect Tabanlı Programlama .

En Boy Odaklı Programlama , üst sınıfı "öneriler" olarak adlandırılan bir şeyle kapsamdan sorumlu tutarak, kodu gerçekten değiştirmeden ek davranış ekleyerek bu sorunu ortadan kaldırır. Kesişen endişeler veya küresel değişken kullanımı için çözümler sunar.

Spring , AOP kullanan bir Java çerçevesidir ve geleneksel olarak web uygulamaları için kullanılırken, çekirdek uygulama Java çerçevesi boyunca evrensel olarak kullanılabilir (8.0 dahil). Bu, daha fazla keşfetmek istediğiniz bir yön olabilir.


0

Sorunu anlama

Global değişken nitelendirme statik / örnek çağrı umursamaz veya bir sınıftan diğerine herhangi bir referans geçmeden kodun herhangi bir yerinde erişilebilir ve değiştirilebilir bir değişken olarak düşünün .

Genellikle A sınıfınız varsa

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

ve myvarB sınıfında erişmek ve güncellemek istiyorsanız ,

public class B{

    private A a;

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

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

A sınıfının bir örneğine başvurmanız ve B sınıfındaki değeri şu şekilde güncellemeniz gerekir:

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

Çözüm

Bu yüzden benim çözümüm (iyi bir uygulama olup olmadığından emin olmasam bile), bir singleton kullanmaktır:


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

Artık Global benzersiz örneğini istediğiniz yerde alabilirsiniz:

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
Bu cevap diğer cevapların vermediğini ne ekliyor? Bu cevapta "yeni" bir değer göremiyorum.
EWit

-2

Global Değişken'i tanımlamak için statik Anahtar Kelimeyi kullanabilirsiniz

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

şimdi a ve b'ye istediğiniz yerden erişebilirsiniz

Tools.a;
Tools.b;

Yoy haklısın ... özellikle J2ME'de ... MidLet yapıcısının (proggy başlatma) içine bu kod satırını koyarak NullPointerException'ı önleyebilirsiniz:

new Tools();

Bu, Araçlar'ın onu kullanan herhangi bir talimattan önce tahsis edilmesini sağlar.

Bu kadar!


3
Peki ... Üzgünüm, ama mevcut cevaplar tarafından kapsanmayan bu ek ne?
Gizemli

Belki haklısın ... ama bu cevap bellek ayırma gibi şeyleri açıklıyor.
user2616742

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.