Variabel non-statis tidak dapat dirujuk dari konteks statis


288

Saya telah menulis kode tes ini:

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

Tapi itu memberikan kesalahan berikut:

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

Bagaimana saya mendapatkan metode saya untuk mengenali variabel kelas saya?


Cobalah untuk menghindari penggunaan statis jika memungkinkan. Anda dapat menulis program yang lengkap, semuanya statis, seperti di C. Tapi itu tidak akan menjadi yang sangat bagus. Cobalah menggunakan Java dengan cara yang seharusnya digunakan, sebagai bahasa berorientasi objek.
Erick G. Hagstrom

Jawaban:


294

Anda harus memahami perbedaan antara kelas dan turunan dari kelas itu. Jika Anda melihat mobil di jalan, Anda segera tahu bahwa itu adalah mobil walaupun Anda tidak dapat melihat model atau tipe mana. Ini karena Anda membandingkan apa yang Anda lihat dengan kelas "mobil". Kelas berisi yang mirip dengan semua mobil. Anggap saja sebagai templat atau gagasan.

Pada saat yang sama, mobil yang Anda lihat adalah turunan dari "mobil" kelas karena memiliki semua properti yang Anda harapkan: Ada seseorang yang mengendarainya, ia memiliki mesin, roda.

Jadi kelas mengatakan "semua mobil memiliki warna" dan contoh mengatakan "mobil khusus ini berwarna merah".

Di dunia OO, Anda mendefinisikan kelas dan di dalam kelas, Anda menentukan bidang tipe Color. Ketika kelas dipakai (ketika Anda membuat contoh tertentu), memori dicadangkan untuk warna dan Anda dapat memberikan contoh khusus ini warna. Karena atribut ini spesifik, mereka tidak statis.

Bidang dan metode statis dibagikan dengan semua instance. Mereka adalah untuk nilai-nilai yang spesifik untuk kelas dan bukan contoh khusus. Untuk metode, ini biasanya adalah metode penolong global (seperti Integer.parseInt()). Untuk bidang, biasanya konstanta (seperti jenis mobil, yaitu sesuatu di mana Anda memiliki set terbatas yang tidak sering berubah).

Untuk menyelesaikan masalah Anda, Anda perlu membuat instance (membuat objek) dari kelas Anda sehingga runtime dapat menyimpan memori untuk instance (jika tidak, instance yang berbeda akan saling menimpa yang tidak Anda inginkan).

Dalam kasus Anda, coba kode ini sebagai blok awal:

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
}

main()Metode baru membuat instance kelas yang dikandungnya (terdengar aneh tapi karena main()dibuat dengan kelas bukan dengan instance, ia bisa melakukan ini) dan kemudian memanggil metode instance ( run()).


Saya sedang menjelaskan ini saat ini kepada kolega baru kami - terima kasih atas penjelasan yang luar biasa ini. Ini harus jawaban penerima.
Supahupe

83

Bidang dan metode statis terhubung ke kelas itu sendiri dan bukan instansnya. Jika Anda memiliki kelas A, metode 'normal' b, dan metode statis c, dan Anda membuat turunan adari kelas Anda A, panggilan ke A.c()dan a.b()valid. Metode c()tidak tahu instance mana yang terhubung, sehingga tidak bisa menggunakan bidang non-statis.

Solusi untuk Anda adalah Anda membuat bidang Anda statis atau metode Anda tidak statis. Anda dapat terlihat seperti ini:

class Programm {

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

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

54

Kata statickunci memodifikasi siklus hidup suatu metode atau variabel dalam suatu kelas. Sebuah staticmetode atau variabel dibuat pada saat kelas dimuat. Metode atau variabel yang tidak dideklarasikan sebagai staticdibuat hanya ketika kelas dipakai sebagai objek misalnya dengan menggunakan newoperator.

Siklus hidup suatu kelas, secara umum, adalah:

  1. kode sumber untuk kelas ditulis menciptakan templat atau pola atau stempel yang kemudian dapat digunakan untuk
  2. buat objek dengan newoperator menggunakan kelas untuk membuat instance kelas sebagai objek aktual dan kemudian ketika dilakukan dengan objek
  3. hancurkan objek yang mengambil kembali sumber daya yang dipegangnya seperti memori selama pengumpulan sampah.

Untuk memiliki titik masuk awal untuk suatu aplikasi, Java telah mengadopsi konvensi bahwa program Java harus memiliki kelas yang berisi metode dengan nama yang disepakati atau khusus. Metode khusus ini disebut main(). Karena metode harus ada apakah kelas yang berisi metode utama telah dipakai atau tidak, main()metode harus dideklarasikan dengan staticpengubah sehingga segera setelah kelas dimuat, main()metode tersedia.

Hasilnya adalah bahwa ketika Anda memulai aplikasi Java Anda dengan baris perintah seperti java helloworldserangkaian tindakan terjadi. Pertama-tama Java Virtual Machine dijalankan dan diinisialisasi. Selanjutnya file helloworld.class yang berisi kode Java yang dikompilasi dimuat ke Java Virtual Machine. Kemudian Java Virtual Machine mencari metode di helloworldkelas yang dipanggil main(String [] args). metode ini harus sedemikian staticsehingga akan ada walaupun kelas belum benar-benar dipakai sebagai objek. Java Virtual Machine tidak membuat turunan kelas dengan membuat objek dari kelas. Itu hanya memuat kelas dan memulai eksekusi pada main()metode.

Jadi Anda perlu membuat instance kelas Anda sebagai objek dan kemudian Anda dapat mengakses metode dan variabel kelas yang belum dideklarasikan dengan staticpengubah. Setelah program Java Anda mulai dengan main()fungsi, Anda dapat menggunakan variabel atau metode apa pun yang memiliki pengubah staticsejak mereka ada sebagai bagian dari kelas yang sedang dimuat.

Namun, variabel dan metode kelas yang berada di luar main()metode yang tidak memiliki staticpengubah tidak dapat digunakan sampai turunan kelas telah dibuat sebagai objek dalam main()metode. Setelah membuat objek, Anda dapat menggunakan variabel dan metode objek. Upaya untuk menggunakan variabel dan metode kelas yang tidak memiliki staticpengubah tanpa melalui objek kelas ditangkap oleh kompiler Java pada waktu kompilasi dan ditandai sebagai kesalahan.

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

Mari kita analisis program Anda terlebih dahulu .. Dalam program Anda, metode pertama Anda adalah main(), dan ingatlah itu adalah metode statis ... Kemudian Anda mendeklarasikan variabel lokal untuk metode itu (compareCount, rendah, tinggi, dll.). Cakupan variabel ini hanya metode yang dideklarasikan, terlepas dari itu metode statis atau non-statis. Jadi, Anda tidak dapat menggunakan variabel-variabel di luar metode itu. Ini adalah kesalahan dasar yang Anda buat.

Kemudian kita sampai pada poin berikutnya. Anda bilang statis membunuh Anda. (Mungkin membunuhmu tetapi itu hanya memberi hidup pada programmu !!) Pertama-tama kamu harus memahami hal dasar. * Metode statis hanya memanggil metode statis dan hanya menggunakan variabel statis. * Variabel statis atau metode statis tidak tergantung pada instance kelas apa pun. (Yaitu Jika Anda mengubah keadaan variabel statis itu akan tercermin dalam semua objek dari kelas) * Karena ini Anda menyebutnya sebagai variabel kelas atau metode kelas. Dan masih banyak lagi tentang kata kunci "statis". Saya harap sekarang Anda mendapatkan idenya. Pertama-tama ubahlah ruang lingkup variabel dan nyatakan sebagai statis (untuk dapat menggunakannya dalam metode statis).

Dan saran untuk Anda adalah: Anda salah memahami gagasan tentang ruang lingkup variabel dan fungsi statis. Dapatkan ide yang jelas tentang itu.


11

Yang paling mendasar adalah variabel statis atau metode statis berada di level kelas. Variabel atau metode tingkat kelas dimuat sebelum metode tingkat variabel atau variabel. Dan jelas hal yang tidak dimuat tidak dapat digunakan. Jadi kompiler java tidak membiarkan hal-hal yang harus ditangani pada saat run diselesaikan pada waktu kompilasi. Itu sebabnya itu memberi Anda kesalahan hal-hal non-statis tidak dapat disebut dari konteks statis. Anda hanya perlu membaca tentang Lingkup Tingkat Kelas, Lingkup Tingkat Instans dan Lingkup Lokal.


8

Untuk dapat mengaksesnya dari metode statis Anda, mereka perlu variabel anggota statis, seperti ini:

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

Sekarang Anda dapat menambahkan / menggunakan instance dengan dalam metode ini

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

Contoh yang sangat solid yang saya gunakan sebagai template untuk merevisi file src kompleks menjadi struktur yang tepat.
XMAN

3

Saya akan mencoba menjelaskan hal yang statis kepada Anda. Pertama-tama variabel statis bukan milik instance kelas tertentu. Mereka dikenali dengan nama kelasnya. Metode statis lagi bukan milik lagi untuk contoh tertentu. Mereka hanya dapat mengakses variabel statis. Bayangkan Anda memanggil MyClass.myMethod () dan myMethod adalah metode statis. Jika Anda menggunakan variabel non-statis di dalam metode ini, bagaimana ia bisa tahu variabel mana yang akan digunakan? Itu sebabnya Anda dapat menggunakan metode statis hanya variabel statis. Saya ulangi lagi bahwa mereka TIDAK milik contoh tertentu.


2
  • Hal pertama adalah mengetahui perbedaan antara instance kelas, dan kelas itu sendiri. Kelas memodelkan properti tertentu, dan perilaku keseluruhan dalam konteks properti tersebut. Sebuah instance akan menentukan nilai spesifik untuk properti tersebut.

  • Apa pun yang terikat dengan kata kunci statis tersedia dalam konteks kelas daripada dalam konteks instance kelas

  • Sebagai akibat wajar atas

    1. variabel dalam suatu metode tidak boleh statis
    2. bidang statis, dan metode harus dipanggil menggunakan nama kelas misalnya MyProgram7.main (...)
  • Masa pakai bidang / metode statis sama dengan masa pakai aplikasi Anda

Misalnya Katakanlah, mobil memiliki warna properti, dan menunjukkan perilaku 'gerak'. Sebuah contoh dari mobil itu adalah Beetle Red Volkswagen yang bergerak pada kecepatan 25 km / jam.

Sekarang properti statis mobil akan menjadi jumlah roda (4) di jalan, dan ini akan berlaku untuk semua mobil.

HTH


1

ClassLoader bertanggung jawab untuk memuat file kelas. Mari kita lihat apa yang terjadi ketika kita menulis kelas kita sendiri.

Contoh 1:

class StaticTest {

      static int a;
      int b;
      int c;
}

Sekarang kita dapat melihat bahwa kelas "StaticTest" memiliki 3 bidang. Tapi sebenarnya tidak ada b, variabel anggota c. Tapi mengapa ???. OK, jangan sampai. Di sini b, c adalah variabel instan. Karena variabel instan mendapat memori pada saat pembuatan objek. Jadi di sini b, c belum mendapatkan memori apa pun. Itu sebabnya tidak ada keberadaan b, c. Jadi hanya ada keberadaan a. Untuk ClassLoader hanya memiliki satu informasi tentang a. ClassLoader belum mengenali b, c karena objeknya belum dipakai.

Mari kita lihat contoh lain: Contoh 2:

class StaticTest {

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


      public static void main(String []cmd) {

             display();       
      }

}

Sekarang jika kita mencoba mengkompilasi kode ini kompiler akan memberikan kesalahan CE CE: tampilan metode non-statis () tidak dapat dirujuk dari konteks statis.

Sekarang Untuk ClassLoader sepertinya:

class StaticTest {

      public static void main(String []cmd) {

             display();       
      }

}

Dalam Contoh 2 kesalahan CE adalah karena kita memanggil metode non statis dari konteks statis. Jadi tidak mungkin bagi ClassLoader untuk mengenali tampilan metode () pada waktu kompilasi. Sehingga terjadi kesalahan waktu kompilasi.


Mungkin mengirimkan jawaban Anda secara tidak sengaja sebelum Anda berhasil menyelesaikannya? Harap edit dan tambahkan konten yang hilang, terima kasih!
plamut

1

Sebelum Anda memanggil metode instance atau variabel instan, diperlukan objek (Instance). Ketika variabel instance dipanggil dari compiler metode statis tidak tahu objek mana yang dimiliki variabel ini. Karena metode statis tidak memiliki objek (Hanya satu salinan selalu). Saat Anda memanggil variabel instan atau metode instan dari metode instan, ia merujuk thisobjek. Ini berarti variabel milik objek apa pun yang dibuat dan masing-masing objek memiliki salinan metode dan variabel contoh itu sendiri.

Variabel statis ditandai sebagai staticdan variabel instan tidak memiliki kata kunci spesifik.


0

Ini sedikit berbeda untuk menjelaskan tentang kata kunci statis untuk semua pemula.
Anda akan mengetahuinya dengan jelas ketika Anda bekerja lebih banyak dengan Kelas dan Objek.

| * | Statis: Item statis dapat dipanggil dengan Nama Kelas
Jika Anda mengamati dalam kode, Beberapa fungsi secara langsung dipanggil dengan Nama kelas seperti

NamCls.NamFnc();

System.out.println();

Ini karena NamFnc dan println akan dideklarasikan menggunakan kata kunci statis sebelum mereka.

| * | Non Statis: Item Non Statis dapat dipanggil dengan Kelas Variabel
Jika tidak statis, Anda memerlukan variabel kelas,
beri titik setelah variabel kelas,
lalu panggil fungsi.

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


Kode di bawah ini menjelaskan Anda dengan rapi

| * | Fungsi statis dan non Statis di kelas:

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


| * | Kelas Statis dan Non Statis di dalam Kelas:

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);
        }
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.