1. kata kunci statik
Ternyata untuk pembolehubah ahli dalam kelas, setiap objek baharu mempunyai pembolehubah ahlinya sendiri, kerana pembolehubah ahli ini bukan pembolehubah ahli statik. Untuk pembolehubah ahli statik, hanya terdapat satu salinan pembolehubah ahli ini dan salinan ini dikongsi oleh semua objek kelas ini.
1.1 Perbezaan antara pembolehubah ahli statik dan pembolehubah bukan statik
Ambil contoh berikut sebagai contoh
package cn.galc.test; public class Cat { /** * 静态成员变量 */ private static int sid = 0; private String name; int id; Cat(String name) { this.name = name; id = sid++; } public void info() { System.out.println("My Name is " + name + ",NO." + id); } public static void main(String[] args) { Cat.sid = 100; Cat mimi = new Cat("mimi"); Cat pipi = new Cat("pipi"); mimi.info(); pipi.info(); } }
Fahami proses pelaksanaan keseluruhan program dengan melukis gambar rajah analisis memori
Apabila melaksanakan ayat pertama program: Cat.sid = 100;, sid di sini ialah pembolehubah ahli statik Pembolehubah statik disimpan dalam kawasan data (seg data), jadi mula-mula peruntukkan ruang kecil dalam kawasan data sid, selepas ayat pertama dilaksanakan, terdapat nilai dalam sid, iaitu 100.
Gambar rajah susun atur memori pada masa ini adalah seperti berikut
Langkah seterusnya ialah melaksanakan program untuk:
Kucing mimi = Kucing baharu(“mimi”);
Di sini, Cat pembina(Nama rentetan) kelas Cat dipanggil Kaedah pembina ditakrifkan seperti berikut:
Kucing (Nama rentetan){
this.name = nama;
id=sid ;
}
Apabila memanggil, mula-mula peruntukkan sekeping kecil memori mm dalam memori tindanan, yang mengandungi alamat objek contoh kelas Cat dalam memori timbunan mm ialah objek rujukan objek kelas Cat dalam memori timbunan . Pembina ini mengisytiharkan pembolehubah parameter formal jenis rentetan, jadi "mimi" diserahkan kepada pembina sebagai parameter sebenar Memandangkan pemalar rentetan diperuntukkan dan disimpan dalam kawasan data, terdapat sejumlah kecil memori dalam kawasan data. Digunakan untuk menyimpan rentetan "mimi". Pengagihan memori pada masa ini adalah seperti yang ditunjukkan di bawah:
Apabila pembina dipanggil, mula-mula peruntukkan ruang kecil dalam memori tindanan untuk nama parameter formal Kemudian rentetan "mimi" dihantar ke nama sebagai parameter sebenar . Jenis, kecuali untuk empat dan lapan jenis data asas, semua yang lain adalah jenis rujukan, jadi ia boleh dianggap bahawa rentetan juga merupakan objek. Jadi ini bersamaan dengan menghantar rujukan objek "mimi" kepada nama, jadi sekarang nama menunjuk kepada "mimi". Jadi susun atur memori pada masa ini adalah seperti yang ditunjukkan di bawah:
Seterusnya laksanakan kod dalam badan pembina:
this.name=name;
Ini di sini merujuk kepada objek semasa, yang merujuk kepada kucing dalam ingatan timbunan. Di sini, nilai yang terkandung dalam nama dalam tindanan dihantar kepada atribut nama objek kucing dalam memori timbunan, jadi nilai yang terkandung dalam nama itu juga boleh ditemui dalam objek rentetan "mimi" yang terletak di kawasan data. Pada masa ini, nama ini juga merupakan objek rujukan bagi objek rentetan "mimi". Melalui nilai atributnya, objek rentetan "mimi" yang terletak di kawasan data boleh ditemui. Pengagihan memori pada masa ini adalah seperti yang ditunjukkan di bawah:
Seterusnya, laksanakan satu lagi baris kod dalam badan kaedah: id=sid;
Di sini nilai sid dihantar ke id, jadi nilai id ialah 100. Selepas sid diluluskan, tambah 1 sendiri, dan sid menjadi 101. Susun atur memori pada masa ini ditunjukkan dalam rajah di bawah.
Pada ketika ini, kaedah pembina dipanggil, dan semua ruang memori yang diduduki oleh pembolehubah tempatan yang diperuntukkan kepada kaedah pembina ini akan hilang, jadi memori nama yang terletak di ruang tindanan hilang. Rujukan kepada objek rentetan "mimi" dalam kawasan data dalam memori tindanan juga hilang Pada masa ini, hanya rujukan kepada objek rentetan "mimi" dalam ingatan timbunan. Susun atur memori pada masa ini adalah seperti yang ditunjukkan di bawah:
Pelaksanaan seterusnya: Cat pipi = new Cat(“pipi”);
Berikut ialah panggilan kedua kepada kaedah pembina Cat().
最后两句代码是调用info()方法打印出来,打印结果如下:
通过这个程序,看出来了这个静态成员变量sid的作用,它可以计数。每当有一只猫new出来的时候,就给它记一个数。让它自己往上加1。
程序执行完后,内存中的整个布局就如上图所示了。一直持续到main方法调用完成的前一刻。
这里调用构造方法Cat(String name) 创建出两只猫,首先在栈内存里面分配两小块空间mimi和pipi,里面分别装着可以找到这两只猫的地址,mimi和pipi对应着堆内存里面的两只猫的引用。这里的构造方法声明有字符串类型的变量,字符串常量是分配在数据区里面的,所以这里会把传过来的字符串mimi和pipi都存储到数据区里面。所以数据区里面分配有存储字符串mimi和pipi的两小块内存,里面装着字符串“mimi”和“pipi”,字符串也是引用类型,除了那四类8种的基础数据类型之外,其他所有的数据类型都是引用类型。所以可以认为字符串也是一个对象。
这里是new了两只猫出来,这两只猫都有自己的id和name属性,所以这里的id和name都是非静态成员变量,即没有static修饰。所以每new出一只新猫,这只新猫都有属于它自己的id和name,即非静态成员变量id和name是每一个对象都有单独的一份。但对于静态成员变量来说,只有一份,不管new了多少个对象,哪怕不new对象,静态成员变量在数据区也会保留一份。如这里的sid一样,sid存放在数据区,无论new出来了多少只猫在堆内存里面,sid都只有一份,只在数据区保留一份。
静态成员变量是属于整个类的,它不属于专门的某个对象。那么如何访问这个静态成员变量的值呢?首先第一点,任何一个对象都可以访问这个静态的值,访问的时候访问的都是同一块内存。第二点,即便是没有对象也可以访问这个静态的值,通过“类名.静态成员变量名”来访问这个静态的值,所以以后看到某一个类名加上“.”再加上后面有一个东西,那么后面这个东西一定是静态的,如”System.out”,这里就是通过类名(System类)再加上“.”来访问这个out的,所以这个out一定是静态的。
再看下面的这段代码
package cn.galc.test; public class Cat { /** * 这里面的sid不再是静态成员变量了,因为没有static修饰符, * 此时它就是类里面一个普通的非静态成员变量,和id,name一样, * 成为每一个new出来的对象都具有的属性。 */ private int sid = 0; private String name; int id; Cat(String name) { this.name = name; id = sid++; } public void info() { System.out.println("My Name is " + name + ",NO." + id); } public static void main(String[] args) { //Cat.sid = 100;这里不能再使用“类.静态成员变量”的格式来访问sid了,因为sid现在变成了非静态的成员变量了。所以必须要把这句话注释掉,否则无法编译通过。 Cat mimi = new Cat("mimi"); Cat pipi = new Cat("pipi"); mimi.info(); pipi.info(); } }
Satu-satunya perbezaan antara kod ini dan kod sebelumnya ialah pengubah suai statik pembolehubah sid pada masa ini, sid bukan lagi pembolehubah ahli statik, tetapi pembolehubah ahli bukan statik. setiap Objek kucing yang dihasilkan oleh baru akan mempunyai sifat-sifat sampingan yang berasingan. Jadi selepas kod ini dilaksanakan, susun atur dalam memori adalah seperti yang ditunjukkan di bawah:
Oleh kerana sid telah menjadi pembolehubah ahli bukan statik, ia tidak lagi mempunyai fungsi pengiraan. Seperti atribut id dan nama, sid menjadi atribut yang ada pada setiap objek baharu, jadi setiap kucing baharu mempunyai atribut sid yang ditambahkan padanya. Memandangkan sid tidak lagi boleh diakses dalam format "nama kelas. nama objek ahli statik", ayat pertama kod "Cat.sid =100;" tidak boleh digunakan dengan cara ini, jika tidak, ralat kompilasi akan berlaku. Ayat ini mesti diulas untuk berjaya. Oleh kerana nilai sid tidak boleh diakses, nilai sid sentiasa nilai 0 yang diberikan semasa pemulaan. Sehingga pembina dipanggil dan kod id=sid dalam badan kaedah dilaksanakan, sid mula-mula memberikan nilainya sendiri 0 kepada id, jadi nilai id ialah 0, dan kemudian sid menambah 1 pada dirinya sendiri, jadi sid menjadi 1.
Jadi perbezaan antara pembolehubah statik dan pembolehubah bukan statik ialah pembolehubah statik boleh digunakan untuk mengira, tetapi pembolehubah bukan statik tidak boleh.
Jika anda memahami ingatan, anda memahami segala-galanya, dan anda memahami pelbagai bahasa. Semua bahasa tidak lebih daripada ini: memori yang diperuntukkan untuk pembolehubah tempatan sentiasa berada dalam timbunan, memori yang diperuntukkan untuk perkara baharu sentiasa berada di timbunan, dan memori yang diperuntukkan untuk perkara statik sentiasa berada di kawasan data. Selebihnya kod mesti berada dalam kawasan kod. Semua bahasa adalah seperti ini.
Dalam kaedah statik, jika anda ingin mengakses pembolehubah ahli bukan statik, anda tidak boleh mengaksesnya secara langsung Anda mesti mencipta objek baharu dalam kaedah statik untuk mengaksesnya. Jika pembolehubah ahli statik ditambah, maka pembolehubah ahli ini adalah pembolehubah ahli statik dan boleh diakses terus dalam kaedah utama.
Kaedah utama ialah kaedah statik Apabila kaedah utama hendak dilaksanakan, tidak perlu mencipta objek baharu.
Kaedah dinamik dipanggil untuk objek tertentu, manakala kaedah statik tidak dipanggil untuk objek tertentu Ia masih boleh digunakan tanpa objek. Jadi anda boleh menggunakan bentuk "classname.method()" untuk memanggil kaedah statik. Oleh itu, tidak mungkin untuk mengakses pembolehubah ahli bukan statik dalam kaedah utama Ia juga mustahil untuk mengakses kaedah bukan statik dalam kaedah utama, kerana kaedah bukan statik hanya boleh dipanggil untuk objek tertentu tiada objek, ia tidak dapat ditemui Sekarang datang pelaksana kaedah.
Pembolehubah ahli hanya diperuntukkan ruang storan dalam ingatan timbunan apabila objek dicipta oleh yang baharu. Pembolehubah tempatan memperuntukkan ruang storan dalam memori tindanan.
Kaedah statik tidak lagi dipanggil pada objek tertentu, jadi ahli bukan statik tidak boleh diakses.
Ahli bukan statik adalah eksklusif untuk objek tertentu Jika anda ingin mengakses ahli bukan statik, anda mesti mencipta objek baharu untuk mengaksesnya.
Pembolehubah statik boleh diakses melalui nama objek atau nama kelas kedua-duanya mengakses memori yang sama.
Di atas adalah keseluruhan kandungan artikel ini. Terdapat banyak maklumat dan anda perlu membacanya dengan sabar untuk benar-benar mempelajari kata kunci statik java.