Statik olmayan değişkene statik bağlamdan başvuru yapılamaz


288

Bu test kodunu yazdım:

class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}

Ancak aşağıdaki hatayı verir:

Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^

Sınıf değişkenlerimi tanımak için yöntemlerimi nasıl edinebilirim?


Mümkün olduğunca statik kullanmaktan kaçının. Sen olabilir sadece olduğu gibi tam bir program tüm statik yazma C. Ama çok iyi olmayacak. Java'yı nesne yönelimli bir dil olarak kullanılması gerektiği şekilde kullanmaya çalışın.
Erick G. Hagstrom

Yanıtlar:


294

Bir sınıf ile o sınıfın bir örneği arasındaki farkı anlamalısınız. Sokakta bir araba görürseniz, hangi modeli veya türü göremeseniz bile hemen bir araba olduğunu bilirsiniz. Bunun nedeni, gördüklerinizi "araba" sınıfıyla karşılaştırmanızdır . Sınıf, tüm arabalara benzeyen içerir. Bunu bir şablon veya fikir olarak düşünün.

Aynı zamanda, gördüğünüz araba, beklediğiniz tüm özelliklere sahip olduğu için "araba" sınıfının bir örneğidir: Onu kullanan biri var, bir motoru, tekerlekleri var.

Sınıf "tüm arabaların rengi var" der ve örnek "bu araba kırmızıdır" der.

OO dünyasında, sınıfı ve sınıfın içinde bir yazı alanı tanımlarsınız Color. Sınıf somutlaştırıldığında (belirli bir örnek oluşturduğunuzda), bellek renk için ayrılır ve bu özel örneğe bir renk verebilirsiniz. Bu öznitelikler spesifik olduğu için statik değildirler.

Statik alanlar ve yöntemler tüm örneklerle paylaşılır. Belirli bir örnek için değil, sınıfa özgü değerler içindir. Yöntemler için, bu genellikle küresel yardımcı yöntemlerdir (gibi Integer.parseInt()). Alanlar için genellikle sabittir (araba türleri gibi, yani sık sık değişmeyen sınırlı bir kümeye sahip olduğunuz bir şey).

Sorununuzu çözmek için, çalışma zamanının örnek için bellek ayırabilmesi amacıyla sınıfınızın bir örneğini (nesne oluştur) başlatmanız gerekir (aksi takdirde, farklı örnekler istemediğiniz birbirlerinin üzerine yazılır).

Sizin durumunuzda, bu kodu bir başlangıç ​​bloğu olarak deneyin:

public static void main (String[] args)
{
    try
    {
        MyProgram7 obj = new MyProgram7 ();
        obj.run (args);
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
}

// instance variables here

public void run (String[] args) throws Exception
{
    // put your code here
}

Yeni main()yöntem, içerdiği sınıfın bir örneğini oluşturur (kulağa garip gelir, ancak main()örnek yerine sınıfla oluşturulduğundan, bunu yapabilir) ve sonra bir örnek yöntemi ( run()) çağırır .


Bunu şu anda yeni meslektaşımıza açıklıyorum - bu harika açıklama için teşekkürler. Bu kabul yanıtını vermelidir.
Supahupe

83

Statik alanlar ve yöntemler, sınıfın kendisine değil örneklerine bağlıdır. Eğer bir sınıf varsa A, 'normal' yöntemini bve statik bir yöntem cve bir örneğini yapmak aiçin sınıfın A, yapılan çağrılar A.c()ve a.b()geçerlidir. Yöntemin c()hangi örneğin bağlı olduğu hakkında hiçbir fikri yoktur, bu nedenle statik olmayan alanları kullanamaz.

Sizin için çözüm, alanlarınızı statik veya yöntemlerinizi statik olmayan hale getirmenizdir. O zaman ana şöyle görünebilir:

class Programm {

    public static void main(String[] args) {
        Programm programm = new Programm();
        programm.start();
    }

    public void start() {
        // can now access non-static fields
    }
}

54

staticAnahtar kelime bir sınıf içinde bir yöntem veya değişkenin yaşam döngüsünü değiştirir. staticSınıf yüklendiğinde bir yöntem veya değişken oluşturulur. Olarak bildirilmeyen bir yöntem veya değişken staticyalnızca sınıf, örneğin newişleç kullanılarak bir nesne olarak başlatıldığında oluşturulur .

Bir sınıfın yaşam döngüsü, geniş anlamda:

  1. sınıfın kaynak kodu, daha sonra aşağıdakiler için kullanılabilecek bir şablon veya desen veya damga oluşturarak yazılır
  2. bir nesne oluşturmak newnesne ile yapıldığında daha sonra gerçek bir nesne olarak sınıfın bir örneği yapmak ve sınıfı kullanılarak operatör
  3. çöp toplama sırasında bellek gibi elinde bulunan kaynakları geri alan nesneyi yok etmek.

Java, bir uygulama için ilk giriş noktasına sahip olmak amacıyla, Java programının üzerinde anlaşılan veya özel adda bir yöntem içeren bir sınıfa sahip olması gerektiği kuralını kabul etmiştir. Bu özel yönteme denir main(). Ana yöntemi içeren sınıfın somutlaştırılmış olsun ya da olmasın, main()yöntemin var olması gerektiğinden static, sınıf yüklenir yüklenmez main()yöntem kullanılabilir olacak şekilde yöntemin değiştiriciyle bildirilmesi gerekir .

Sonuç, Java uygulamanızı java helloworldbir dizi eylem gibi bir komut satırı ile başlattığınızda ortaya çıkar. Her şeyden önce bir Java Sanal Makinesi başlatılır ve başlatılır. Ardından, derlenen Java kodunu içeren helloworld.class dosyası Java Sanal Makinesi'ne yüklenir. Daha sonra Java Sanal Makinesi, helloworldsınıfta çağrılan bir yöntem arar main(String [] args). bu yöntem static, sınıf aslında bir nesne olarak somutlaştırılmamış olsa bile var olacak şekilde olmalıdır . Java Sanal Makinesi, sınıftan bir nesne oluşturarak sınıfın bir örneğini oluşturmaz. Sadece sınıfı yükler ve main()yöntemde yürütmeye başlar .

Bu nedenle, nesne olarak sınıfınızın bir örneğini oluşturmanız ve daha sonra sınıfın staticdeğiştiriciyle bildirilmemiş yöntemlere ve değişkenlere erişmeniz gerekir . Java programınız main()işleve başladıktan sonra, değiştirilmekte olan değişkenleri veya yöntemleri staticyüklenen sınıfın bir parçası olarak var olduğundan kullanabilirsiniz.

Bununla birlikte, sınıfın değiştiriciye main()sahip olmayan yönteminin dışındaki değişkenleri ve yöntemleri, sınıfın staticbir örneği main()yöntem içinde nesne olarak oluşturulana kadar kullanılamaz. Nesneyi oluşturduktan sonra, nesnenin değişkenlerini ve yöntemlerini kullanabilirsiniz. Sınıfın staticbir nesnesinden geçmeden değiştiriciye sahip olmayan sınıfın değişkenlerini ve yöntemlerini kullanma girişimi derleme zamanında Java derleyicisi tarafından yakalanır ve hata olarak işaretlenir.

import java.io.*;

class HelloWorld {
    int myInt;      // this is a class variable that is unique to each object
    static int myInt2;  // this is a class variable shared by all objects of this class

    static void main (String [] args) {
        // this is the main entry point for this Java application
        System.out.println ("Hello, World\n");
        myInt2 = 14;    // able to access the static int
        HelloWorld myWorld = new HelloWorld();
        myWorld.myInt = 32;   // able to access non-static through an object
    }
}

11

Önce programınızı analiz edelim .. Programınızda, ilk yönteminiz main()ve bunu statik yöntem olduğunu aklınızda bulundurun ... O zaman bu yöntem için yerel değişkeni beyan edersiniz (comparCount, low, high, etc ..). Bu değişkenin kapsamı, statik veya statik olmayan bir yöntem olmasına bakılmaksızın, yalnızca bildirilen yöntemdir. Dolayısıyla bu değişkenleri bu yöntemin dışında kullanamazsınız. Bu u yapılan temel hatadır.

Sonra bir sonraki noktaya geliyoruz. Statikin seni öldürdüğünü söylemiştin. (Sizi öldürüyor olabilir ama sadece programınıza hayat verir !!) Öncelikle temel şeyi anlamalısınız. * Statik yöntem yalnızca statik yöntemi çağırır ve yalnızca statik değişkeni kullanır. * Statik değişken veya statik yöntem bu sınıfın hiçbir örneğine bağlı değildir. (yani, statik değişkenin herhangi bir durumunu değiştirirseniz, sınıfın tüm nesnelerinde yansıtılır) * Bu nedenle, bunu sınıf değişkeni veya sınıf yöntemi olarak adlandırırsınız. Ve "statik" anahtar kelime hakkında çok daha fazlası var. Umarım şimdi fikri anlarsın. Önce değişkenin kapsamını değiştirin ve statik olarak bildirin (statik yöntemlerde kullanabilmek için).

Ve sizin için tavsiye: değişkenlerin kapsamı ve statik işlevsellik fikrini yanlış anladınız. Bu konuda net bir fikir edinin.


11

En temel şey statik değişkenler veya statik yöntemler sınıf düzeyindedir. Sınıf düzeyi değişkenleri veya yöntemleri, örnek düzeyi yöntemlerinden veya değişkenlerinden önce yüklenir.Açık olarak yüklenmemiş olan şey kullanılamaz. Yani java derleyici çalışma zamanında işlenmesine izin vermez derleme zamanında çözülür. Bu nedenle size statik olmayan şeylerden statik içerikten kaynaklanamayan hata veriyor. Sadece Sınıf Düzeyi Kapsamı, Örnek Düzeyi Kapsamı ve Yerel Kapsam'ı okumalısınız.


8

Onlara statik yöntemlerinizden erişebilmek için statik üye değişkenleri olması gerekir, örneğin:

public class MyProgram7 {
  static Scanner scan = new Scanner(System.in);
  static int compareCount = 0;
  static int low = 0;
  static int high = 0;
  static int mid = 0;  
  static int key = 0;  
  static Scanner temp;  
  static int[]list;  
  static String menu, outputString;  
  static int option = 1;  
  static boolean found = false;

  public static void main (String[]args) throws IOException {
  ...

7

Artık yöntemde örnek ekleyebilir / kullanabilirsiniz

public class Myprogram7 {

  Scanner scan;
  int compareCount = 0;
  int low = 0;
  int high = 0;
  int mid = 0;  
  int key = 0;  
  Scanner temp;  
  int[]list;  
  String menu, outputString;  
  int option = 1;  
  boolean found = false;  

  private void readLine() {

  }

  private void findkey() {

  }

  private void printCount() {

  }
  public static void main(String[] args){

    Myprogram7 myprg=new Myprogram7();
    myprg.readLine();
    myprg.findkey();
    myprg.printCount();
  }
}

Karmaşık bir src dosyasını uygun bir yapıya dönüştürmek için şablon olarak kullandığım çok sağlam bir örnek.
XMAN

3

Statik şeyi size açıklamaya çalışacağım. Her şeyden önce, statik değişkenler sınıfın belirli bir örneğine ait değildir. Sınıf adıyla tanınırlar. Statik yöntemler yine belirli bir örneğe ait değildir. Yalnızca statik değişkenlere erişebilirler. MyClass.myMethod () öğesini çağırdığınızı ve myMethod'un statik bir yöntem olduğunu düşünün. Yöntemin içinde statik olmayan değişkenler kullanırsanız, yeryüzündeki cehennem hangi değişkenlerin kullanılacağını nasıl bilir? Bu nedenle statik yöntemlerden yalnızca statik değişkenleri kullanabilirsiniz. Tekrar ediyorum, herhangi bir özel örneğe ait DEĞİLDİR.


2
  • İlk şey, bir sınıf örneği ile sınıfın kendisi arasındaki farkı bilmektir. Bir sınıf belirli özellikleri ve bütünün bu özellikler bağlamındaki davranışını modeller. Bir örnek, bu özellikler için belirli değerler tanımlayacaktır.

  • Statik anahtar kelimeye bağlı olan her şey, sınıfın bir örneği bağlamında değil, sınıf bağlamında kullanılabilir

  • Yukarıdakilere bir sonuç olarak

    1. yöntem içindeki değişkenler statik olamaz
    2. statik alanlar ve yöntemler sınıf adı kullanılarak çağrılmalıdır, örn. MyProgram7.main (...)
  • Statik bir alanın / yöntemin ömrü uygulamanızın ömrüne eşittir

Örneğin Say, otomobilin özellik rengi vardır ve 'hareket' davranışı sergiler. Arabanın bir örneği, 25 km / s hızla hareket eden bir Kırmızı Volkswagen Beetle olacaktır.

Şimdi arabanın statik bir özelliği, yoldaki tekerlek sayısı (4) olacaktır ve bu tüm arabalar için geçerli olacaktır.

HTH


1

Sınıf dosyalarını yüklemek ClassLoader'ın sorumluluğundadır. Kendi sınıflarımızı yazdığımızda ne olacağını görelim.

Örnek 1:

class StaticTest {

      static int a;
      int b;
      int c;
}

Şimdi "StaticTest" sınıfının 3 alanı olduğunu görebiliyoruz. Ama aslında b, c üye değişkeni yok ama neden ???. Tamam bakalım. Burada b, c, örnek değişkendir. Çünkü örnek değişkeni, nesne oluşturma sırasında belleği alır. Yani burada b, c henüz hafıza kazanmıyor. Bu yüzden b, c'nin varlığı yoktur. Yani sadece bir. ClassLoader için a hakkında yalnızca bir bilgi vardır. ClassLoader henüz b, c'yi tanımıyor çünkü nesne henüz somutlaştırılmadı.

Başka bir örnek görelim: Örnek 2:

class StaticTest {

      public void display() {
          System.out.println("Static Test");
      }


      public static void main(String []cmd) {

             display();       
      }

}

Şimdi bu kodu derlemeye çalışırsak derleyici CE hatası verecektir. CE: statik olmayan yöntem display () statik bir bağlamdan başvurulamaz.

ClassLoader için şu şekilde görünüyor:

class StaticTest {

      public static void main(String []cmd) {

             display();       
      }

}

Örnek 2'de CE hatası, statik olmayan bir yöntemden statik olmayan bir yöntem çağırmamızdır. Bu nedenle ClassLoader'ın derleme zamanında method display () yöntemini tanıması mümkün değildir. Bu nedenle derleme zamanı hatası oluşur.


Muhtemelen cevabınızı bitirmeden önce kazara mı göndermiştiniz? Lütfen düzenleyin ve eksik içeriği ekleyin, teşekkürler!
plamut

1

Bir örnek yöntemini veya örnek değişkenini çağırmadan önce Bir nesneye (Örnek) ihtiyaç duyar. Statik yöntemden örnek değişkeni çağrıldığında derleyici bu değişkenin hangi nesneye ait olduğunu bilmez. Çünkü statik yöntemlerin bir nesnesi yoktur (Her zaman yalnızca bir kopya). Örnek yönteminden bir örnek değişkeni veya örnek yöntemlerini çağırdığınızda, thisnesneye başvurur . Değişkenin, oluşturulan her nesneye ait olduğu ve her nesnenin kendi örnek yöntemleri ve değişkenleri kopyası olduğu anlamına gelir.

Statik değişkenler olarak işaretlenir staticve örnek değişkenlerin belirli bir anahtar sözcüğü yoktur.


0

Bu yeni başlayanlar için statik anahtar kelime hakkında açıklamak biraz farklıdır.
Sınıflar ve Nesneler ile daha fazla çalıştığınızda bunu açıkça öğreneceksiniz.

| * | Statik: Statik öğeler Sınıf Adı ile çağrılabilir
Kodlarda gözlemlerseniz, Bazı işlevler doğrudan aşağıdaki gibi Sınıf adları ile çağrılır.

NamCls.NamFnc();

System.out.println();

Çünkü NamFnc ve println, önlerindeki statik anahtar sözcük kullanılarak bildirilecektir.

| * | Statik Olmayan: Statik Olmayan öğeler Sınıf Değişkeni ile çağrılabilir. Statik
değilse, sınıfın bir değişkenine ihtiyacınız vardır
, sınıf değişkeninin arkasına nokta koyun ve
sonra işlevi çağırın.

NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();


Aşağıdaki kod düzgün bir şekilde açıklıyor

| * | Sınıfta statik ve statik olmayan fonksiyon:

public class NamCls
{
    public static void main(String[] args)
    {
        PlsPrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamObjVar.PrnFnc("Tst Txt");
    }

    static void PlsPrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }

    void PrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }
}


| * | Bir Sınıf içindeki statik ve statik olmayan Sınıf:

public class NamCls
{
    public static void main(String[] args)
    {
        NamTicCls NamTicVaj = new NamTicCls();
        NamTicVaj.PrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamNicCls NamNicVar = NamObjVar.new NamNicCls();
        NamNicVar.PrnFnc("Tst Txt");
    }

    static class NamTicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }

    class NamNicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }
}
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.