Bidang statis
Saat kami menyatakan variabel tingkat kelas, kami menunjukkan bahwa nilainya termasuk dalam suatu kelas. Jika Anda tidak melakukan ini, maka nilai variabel akan terikat pada objek yang dibuat menggunakan kelas ini. Apa artinya? Dan faktanya adalah jika variabelnya tidak statis, maka setiap objek baru dari kelas ini akan memiliki nilai variabel ini sendiri, dengan mengubahnya kita mengubahnya secara eksklusif dalam satu objek: Misalnya, kita memiliki kelas Mobil dengan non -variabel statis:
public class Car {
int km;
}
Kemudian di utama:
Car orangeCar = new Car();
orangeCar.km = 100;
Car blueCar = new Car();
blueCar.km = 85;
System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
Output yang kami dapatkan adalah:
Orange car - 100
Blue car - 85
Seperti yang Anda lihat, setiap objek memiliki variabelnya sendiri, yang perubahannya hanya terjadi pada objek ini. Nah, jika kita memiliki variabel statis, maka nilai globalnya sama untuk semua orang: Sekarang kita memiliki Mobil dengan variabel statis:
public class Car {
static int km;
}
Kemudian kode yang sama di main akan ditampilkan ke konsol:
Orange car - 85
Blue car - 85
Bagaimanapun, kita memiliki satu variabel untuk kita semua, dan setiap kali kita mengubahnya. Variabel statis biasanya diakses bukan dengan referensi objek - orangeCar.km, tetapi dengan nama kelas - Car.km
Blok statis
Ada dua blok inisialisasi - reguler dan statis. Blok ini dimaksudkan untuk menginisialisasi variabel internal. Jika bloknya normal, maka variabel internal objek diinisialisasi dengannya, tetapi jika bloknya statis, maka variabel statis (yaitu, variabel kelas) ditugaskan ke blok tersebut. Contoh kelas dengan blok inisialisasi statis:
public class Car {
static int km;
static {
km = 150;
}
}
Metode statis
Metode statis berbeda dari metode biasa karena metode ini juga terikat pada kelas, bukan objek. Properti penting dari metode statis adalah ia hanya dapat mengakses variabel/metode statis. Sebagai contoh, mari kita lihat sebuah kelas yang akan menjadi semacam counter yang melacak pemanggilan metode:
public class Counter {
static int count;
public static void invokeCounter() {
count++;
System.out.println("Current counter value - " + count);
}
}
Sebut saja di main:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
Dan kami mendapatkan output ke konsol:
Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3
Kelas statis di Jawa
Hanya kelas dalam yang bisa menjadi kelas statis. Sekali lagi, kelas ini terikat dengan kelas luar, dan jika kelas luar diwarisi oleh kelas lain, maka kelas ini tidak akan diwarisi. Selain itu, kelas ini dapat diwarisi, sama seperti kelas ini dapat diwarisi dari kelas lain dan mengimplementasikan antarmuka. Pada dasarnya, kelas bersarang statis tidak berbeda dengan kelas dalam lainnya, kecuali bahwa objeknya tidak berisi referensi ke objek kelas luar yang membuatnya. Namun, hal ini membuat kelas statis paling mirip dengan kelas non-bersarang biasa, karena satu-satunya perbedaan adalah kelas tersebut digabungkan dengan kelas lain. Dalam beberapa kasus, ini merupakan keuntungan bagi kami, karena dari situ kami memiliki akses ke variabel statis privat kelas luar. Contoh kelas statis bersarang:
public class Vehicle {
public static class Car {
public int km;
}
}
Membuat instance kelas ini dan menetapkan nilai variabel internal:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
Untuk menggunakan metode/variabel/kelas statis, kita tidak perlu membuat objek dari kelas tersebut. Tentu saja, pengubah akses harus diperhitungkan. Misalnya, bidang private
hanya dapat diakses di dalam kelas tempat bidang tersebut dideklarasikan. Bidang protected
tersedia untuk semua kelas di dalam paket ( package ), serta semua kelas turunan di luar paket. Untuk lebih jelasnya, lihat artikel “ pribadi vs dilindungi vs publik ”. Misalkan ada metode statis increment()
di kelas Counter
yang tugasnya menaikkan penghitung count
. Untuk memanggil metode ini, Anda dapat menggunakan pemanggilan form Counter.increment()
. Tidak perlu membuat instance kelas Counter
untuk mengakses bidang atau metode statis. Inilah perbedaan mendasar antara objek statis dan NON-statis (anggota kelas). Izinkan saya mengingatkan Anda sekali lagi bahwa anggota kelas statis langsung menjadi milik kelas tersebut, bukan milik instance-nya. Artinya, nilai variabel statis count
akan sama untuk semua objek bertipe Counter
. Nanti di artikel ini, kita akan melihat aspek dasar penggunaan pengubah statis di Java, serta beberapa fitur yang akan membantu Anda memahami konsep utama pemrograman.
Apa yang harus diketahui setiap programmer tentang pengubah Statis di Java
Di bagian ini, kita akan melihat dasar-dasar penggunaan metode, bidang, dan kelas statis. Mari kita mulai dengan variabelnya.-
Anda TIDAK dapat mengakses anggota kelas yang non-statis dalam konteks statis, seperti metode atau blok. Mengkompilasi kode di bawah ini akan menghasilkan kesalahan:
public class Counter{ private int count; public static void main(String args[]){ System.out.println(count); //compile time error }}
Ini adalah salah satu kesalahan paling umum yang dilakukan oleh programmer Java, terutama pemula. Karena metodenya
main
statis, tetapi variabelnyacount
tidak, dalam hal ini metodeprintln
di dalam metode tersebutmain
akan memunculkan “Kesalahan waktu kompilasi”. -
В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких How «состояние гонки» (race condition).
-
Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый an object для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы How нельзя лучше подходят в качестве методов-фабрик (
factory
), и методов-утorт (utility
). Классjava.lang.Math
— замечательный пример, в котором почти все методы статичны, по этой же причине классы-утorты в Java финализированы (final
). -
Другим важным моментом является то, что вы НЕ можете переопределять (
Override
) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass
), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass
) instead of переопределения. Это явление известно How сокрытие методов (hiding methods
). Это означает, что при обращении к статическому методу, который объявлен How в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:class Vehicle{ public static void kmToMiles(int km){ System.out.println("Inside parent class/static method"); } } class Car extends Vehicle{ public static void kmToMiles(int km){ System.out.println("Inside child class/static method "); } } public class Demo{ public static void main(String args[]){ Vehicle v = new Car(); v.kmToMiles(10); }}
Вывод в консоль:
Внутри родительского класса/статического метода
Код наглядно демонстрирует: несмотря на то, что an object имеет тип
Car
, вызван статический метод из классаVehicle
, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло! -
Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны How «вложенные статические классы» (
nested static class
). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса —HashMap.Entry
, который предоставляет структуру данных внутриHashMap
. Стоит заметить, также How и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявor пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator
), например компаратор по возрасту (AgeComparator
) в классе сотрудники (Employee
). -
Модификатор static также может быть объявлен в статичном блоке, более известным How «Статический блок инициализации» (
Static initializer block
), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему. -
Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных or не статических методов, которые связываются во время исполнения на реальном an objectе. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности or необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утorты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.
-
Важным свойством статического блока является инициализация. Статические поля or переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в Howом они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна
Singleton
. Если вы не используется списокEnum
HowSingleton
, по тем or иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того How кто-нибудь об этом «попросит». Если an object ресурсоёмкий or редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу. -
Selama serialisasi, seperti halnya
transient
variabel, bidang statis tidak diserialisasi. Memang, jika Anda menyimpan data apa pun dalam bidang statis, maka setelah deserialisasi objek baru akan berisi nilai utamanya (default), misalnya, jika bidang statis adalah variabel bertipeint
, maka nilainya setelah deserialisasi akan menjadi nol, jika tipenyafloat
adalah 0,0, jika tipeObject
–null
. Sejujurnya, ini adalah salah satu pertanyaan yang paling sering diajukan mengenai serialisasi dalam wawancara Java. Jangan simpan data terpenting tentang suatu objek di bidang statis! -
Dan akhirnya, mari kita bicara tentang
static import
. Pengubah ini memiliki banyak kesamaan dengan operator standarimport
, tetapi tidak seperti itu, pengubah ini memungkinkan Anda mengimpor satu atau semua anggota statis suatu kelas. Ketika mengimpor metode statis, mereka dapat diakses seolah-olah mereka didefinisikan dalam kelas yang sama, sama halnya ketika mengimpor bidang, kita dapat mengaksesnya tanpa menentukan nama kelas. Fitur ini diperkenalkan di Java versi 1.5, dan bila digunakan dengan benar, akan meningkatkan keterbacaan kode. Konstruksi ini paling sering ditemukan dalam pengujian JUnit , karena Hampir semua pengembang pengujian menggunakanstatic import
metode penegasan, misalnya,assertEquals()
dan duplikatnya yang kelebihan beban. Jika tidak ada yang jelas, selamat datang untuk informasi tambahan .
GO TO FULL VERSION